Просмотр исходного кода

refactor: 将编辑器转为webstorm并处理一些不兼容的情况(VSCode再见了您)

ChenYangfan 6 лет назад
Родитель
Сommit
936b75eb61
45 измененных файлов с 226 добавлено и 195 удалено
  1. 5 0
      public/index.html
  2. 6 7
      src/App.vue
  3. 1 6
      src/common/button-common.scss
  4. 3 4
      src/common/slide/item.scss
  5. 1 1
      src/common/slide/page.scss
  6. 2 2
      src/common/tab-common.scss
  7. 6 6
      src/components/IconLink.vue
  8. 11 8
      src/components/SearchBar.vue
  9. 6 2
      src/components/SlideListItem.vue
  10. 7 2
      src/layouts/RoleHome.vue
  11. 7 7
      src/plugins/axios.js
  12. 25 29
      src/prototype/Typography.vue
  13. 1 1
      src/server/course.js
  14. 4 4
      src/server/slide.js
  15. 10 10
      src/store/modules/editor.js
  16. 1 1
      src/store/modules/reader.js
  17. 13 13
      src/utils/default-markdown-fragment.js
  18. 9 5
      src/views/Home.vue
  19. 4 4
      src/views/editor/EditorView.vue
  20. 15 13
      src/views/editor/components/EditableItem.vue
  21. 3 2
      src/views/editor/components/EditingPage.vue
  22. 8 8
      src/views/editor/components/Editor.vue
  23. 2 2
      src/views/reader/ReaderView.vue
  24. 5 3
      src/views/reader/components/Reader.vue
  25. 1 1
      src/views/reader/components/ReaderItem.vue
  26. 3 2
      src/views/reader/components/ReaderPage.vue
  27. 4 4
      src/views/reader/components/components/DiscussButtonLarge.vue
  28. 4 2
      src/views/reader/components/components/DiscussButtonSmall.vue
  29. 4 2
      src/views/reader/components/components/MarkerButton.vue
  30. 5 3
      src/views/reader/components/components/ReadModeButtonGroup.vue
  31. 6 6
      src/views/reader/components/components/ScalePad.vue
  32. 2 2
      src/views/student/StudentHomeView.vue
  33. 1 1
      src/views/student/tabs/DiscussionTab.vue
  34. 1 1
      src/views/student/tabs/HistoryTab.vue
  35. 1 1
      src/views/student/tabs/HomeTab.vue
  36. 1 1
      src/views/student/tabs/InfoTab.vue
  37. 1 1
      src/views/student/tabs/PersonalTab.vue
  38. 1 1
      src/views/student/tabs/SearchTab.vue
  39. 1 1
      src/views/teacher/TeacherHomeView.vue
  40. 22 17
      src/views/teacher/tabs/AddTab.vue
  41. 1 1
      src/views/teacher/tabs/DiscussionTab.vue
  42. 5 3
      src/views/teacher/tabs/HomeTab.vue
  43. 1 1
      src/views/teacher/tabs/InfoTab.vue
  44. 1 1
      src/views/teacher/tabs/PersonalTab.vue
  45. 5 3
      src/views/teacher/tabs/SearchTab.vue

+ 5 - 0
public/index.html

@@ -7,6 +7,11 @@
   <meta name="viewport" content="width=device-width,initial-scale=1.0">
   <link rel="icon" href="<%= BASE_URL %>favicon.ico">
   <title>SEEC 课堂助手</title>
+  <style>
+    :root {
+      font-family: -apple-system, BlinkMacSystemFont, 'DengXian', sans-serif;
+    }
+  </style>
 </head>
 
 <body>

+ 6 - 7
src/App.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <router-view />
+    <router-view/>
   </div>
 </template>
 
@@ -19,11 +19,10 @@ body {
 @font-face {
   font-family: 'iconfont'; /* project id 1598214 */
   src: url('//at.alicdn.com/t/font_1598214_alt7gplefub.eot');
-  src: url('//at.alicdn.com/t/font_1598214_alt7gplefub.eot?#iefix')
-      format('embedded-opentype'),
-    url('//at.alicdn.com/t/font_1598214_alt7gplefub.woff2') format('woff2'),
-    url('//at.alicdn.com/t/font_1598214_alt7gplefub.woff') format('woff'),
-    url('//at.alicdn.com/t/font_1598214_alt7gplefub.ttf') format('truetype'),
-    url('//at.alicdn.com/t/font_1598214_alt7gplefub.svg#iconfont') format('svg');
+  src: url('//at.alicdn.com/t/font_1598214_alt7gplefub.eot?#iefix') format('embedded-opentype'),
+  url('//at.alicdn.com/t/font_1598214_alt7gplefub.woff2') format('woff2'),
+  url('//at.alicdn.com/t/font_1598214_alt7gplefub.woff') format('woff'),
+  url('//at.alicdn.com/t/font_1598214_alt7gplefub.ttf') format('truetype'),
+  url('//at.alicdn.com/t/font_1598214_alt7gplefub.svg#iconfont') format('svg');
 }
 </style>

+ 1 - 6
src/common/button-common.scss

@@ -7,10 +7,5 @@ button {
 
   font-weight: bold;
 
-  border: none;
-  outline: none;
-  background: transparent;
-
-  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
   -webkit-tap-highlight-color: transparent;
-}
+}

+ 3 - 4
src/common/slide/item.scss

@@ -82,7 +82,7 @@ ol>li::before {
   line-height: 0;
   content: counter(li) '.';
   color: $theme-blue;
-   display: inline;
+  display: inline;
   margin-left: -1.6em;
   margin-right: 0.4em;
   text-align: right;
@@ -91,7 +91,7 @@ ol>li::before {
 
 blockquote {
   margin: 1em 0;
-  font-family: serif;
+  font-family: Georgia, 'Times New Roman', Times, serif;
   font-size: 1.5em;
   position: relative;
   font-style: italic;
@@ -122,8 +122,7 @@ img {
 }
 
 .code {
-
-  font-family: monospace;
+  font-family: 'Courier New', Courier, monospace;
   font-weight: bold;
   text-align: left;
   word-break: break-all;

+ 1 - 1
src/common/slide/page.scss

@@ -8,7 +8,7 @@
   padding: 0 2rem;
 
   box-sizing: border-box;
-  font-weight: 500;
+  font-weight: 600;
 
   &>div {
     width: 100%;

+ 2 - 2
src/common/tab-common.scss

@@ -1,4 +1,4 @@
-@import '@/common/theme.scss';
+@import '~@/common/theme.scss';
 
 .tab-wrapper {
   width: 320px;
@@ -46,4 +46,4 @@ a {
   outline: none;
   text-decoration: none;
   color: black;
-}
+}

+ 6 - 6
src/components/IconLink.vue

@@ -5,8 +5,7 @@
         <div
           class="icon"
           :class="currentRouteName === tab.name ? 'active' : ''"
-        >
-          {{ tab.unicode }}
+        >{{ tab.unicode }}
         </div>
       </router-link>
     </template>
@@ -19,13 +18,13 @@
 <script>
 export default {
   props: ['tab'],
-  data() {
+  data () {
     return {
       currentRouteName: this.$route.name
     }
   },
   watch: {
-    $route() {
+    $route () {
       this.currentRouteName = this.$route.name
     }
   }
@@ -33,14 +32,14 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/theme.scss';
+@import '~@/common/theme.scss';
 
 .icon {
   user-select: none;
   cursor: pointer;
   padding: 12px 0;
   text-align: center;
-  font-family: 'iconfont';
+  font-family: 'iconfont', sans-serif;
   font-size: 34px;
   color: $icon-normal-color;
   transition: color 0.1s ease-out;
@@ -49,6 +48,7 @@ export default {
     color: $icon-hover-color;
   }
 }
+
 .active {
   color: $theme-blue;
 }

+ 11 - 8
src/components/SearchBar.vue

@@ -1,10 +1,12 @@
 <template>
   <div>
-    <input
-      type="text"
-      :value="value"
-      @input="$emit('input', $event.target.value)"
-    />
+    <label>
+      <input
+        type="text"
+        :value="value"
+        @input="$emit('input', $event.target.value)"
+      />
+    </label>
     <span class="icon">&#xe6a2;</span>
   </div>
 </template>
@@ -34,19 +36,20 @@ input {
   width: 100%;
   height: 48px;
   line-height: 40px;
-  padding: 0;
-  padding-left: 52px;
+  padding: 0 0 0 52px;
 }
+
 div {
   position: relative;
 }
+
 .icon {
   position: absolute;
   left: 16px;
   user-select: none;
   cursor: pointer;
   text-align: center;
-  font-family: 'iconfont';
+  font-family: 'iconfont', sans-serif;
   font-size: 24px;
   padding: 12px 0;
 }

+ 6 - 2
src/components/SlideListItem.vue

@@ -13,15 +13,16 @@
 
 <script>
 import stateMap from '@/utils/state-chinese-map'
+
 export default {
   props: ['slide'],
-  data() {
+  data () {
     return {
       stateChinese: stateMap[this.slide.state]
     }
   },
   methods: {
-    handleClick() {
+    handleClick () {
       this.$router.push('/editor/' + this.slide.id)
     }
   }
@@ -34,17 +35,20 @@ export default {
   padding-bottom: 8px;
   cursor: pointer;
 }
+
 .content > div {
   color: gray;
   margin: 4px 0;
   font-size: 14px;
 }
+
 .content .title {
   font-size: 1.2em;
   margin: 8px 0;
 
   color: #555;
 }
+
 .tag {
   font-size: 12px;
   display: inline-block;

+ 7 - 2
src/layouts/RoleHome.vue

@@ -8,7 +8,7 @@
       </div>
       <div class="view-container">
         <transition name="fade" mode="out-in">
-          <router-view />
+          <router-view/>
         </transition>
       </div>
     </div>
@@ -23,7 +23,7 @@ export default {}
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/theme.scss';
+@import '~@/common/theme.scss';
 
 .main-container {
   height: 100vh;
@@ -31,9 +31,11 @@ export default {}
   align-items: center;
   justify-content: center;
 }
+
 .menu-container {
   display: flex;
 }
+
 .tab-container {
   padding: 24px 18px 24px 36px;
   display: flex;
@@ -41,16 +43,19 @@ export default {}
   align-items: center;
   justify-content: center;
 }
+
 .view-container {
   padding: 24px 18px;
   width: 460px;
 }
+
 .line {
   height: 0;
   padding: 6px;
   margin: 0 4px 12px 4px;
   border-bottom: 2px solid $icon-normal-color;
 }
+
 .tab {
   margin: -12px 0;
 }

+ 7 - 7
src/plugins/axios.js

@@ -17,11 +17,11 @@ let config = {
 const _axios = axios.create(config)
 
 _axios.interceptors.request.use(
-  function(config) {
+  function (config) {
     // Do something before request is sent
     return config
   },
-  function(error) {
+  function (error) {
     // Do something with request error
     return Promise.reject(error)
   }
@@ -29,27 +29,27 @@ _axios.interceptors.request.use(
 
 // Add a response interceptor
 _axios.interceptors.response.use(
-  function(response) {
+  function (response) {
     // Do something with response data
     return response
   },
-  function(error) {
+  function (error) {
     // Do something with response error
     return Promise.reject(error)
   }
 )
 
-Plugin.install = function(Vue, options) {
+Plugin.install = function (Vue, options) {
   Vue.axios = _axios
   window.axios = _axios
   Object.defineProperties(Vue.prototype, {
     axios: {
-      get() {
+      get () {
         return _axios
       }
     },
     $axios: {
-      get() {
+      get () {
         return _axios
       }
     }

+ 25 - 29
src/prototype/Typography.vue

@@ -53,9 +53,9 @@
         <h3>糟糕的变量名字</h3>
         <div class="code java">
           <code>
-            var x = x - xx <br />
-            var xxx = aretha + SalesTax( aretha )<br />
-            var x = x + LateFee( x1, x ) + xxx <br />
+            var x = x - xx <br/>
+            var xxx = aretha + SalesTax( aretha )<br/>
+            var x = x + LateFee( x1, x ) + xxx <br/>
             var x = x + Interest( x1, x )
           </code>
         </div>
@@ -66,10 +66,10 @@
         <h3>良好的变量名字</h3>
         <div class="code java">
           <code>
-            var balance = balance - lastPayment <br />
-            var monthlyTotal = NewPurchases + SalesTax( newPurchases ) <br />
+            var balance = balance - lastPayment <br/>
+            var monthlyTotal = NewPurchases + SalesTax( newPurchases ) <br/>
             var balance = balance + LateFee( customerID, balance ) +
-            monthlyTotal<br />
+            monthlyTotal<br/>
             var balance = balance + Interest( customerID, balance )
           </code>
         </div>
@@ -156,9 +156,9 @@
             public PageResourceResponse getSlides(@RequestParam(required =
             false, defaultValue = "") String key, @ApiParam(hidden = true)
             @PageableDefault(size = Integer.MAX_VALUE, sort = "updateTime",
-            direction = Sort.Direction.DESC) Pageable pageable) {<br />
+            direction = Sort.Direction.DESC) Pageable pageable) {<br/>
             List&lt;SlideVO&gt; slideVOs = slideService.getSlides(key,
-            pageable);<br />
+            pageable);<br/>
             return PageResourceResponse.of(slideVOs,
             PageResourceResponse.PageInfo.of(pageable.getPageNumber(),
             slideVOs.size())); }
@@ -169,7 +169,7 @@
     <section class="page">
       <div>
         <h3>*#</h3>
-        <br />
+        <br/>
         <div>// 打印 *#</div>
         <div>// 打印一颗 * + 打印一颗 #</div>
       </div>
@@ -178,7 +178,7 @@
       <div>
         <div class="code">
           <code>
-            print("*")<br />
+            print("*")<br/>
             print("#")
           </code>
         </div>
@@ -186,7 +186,7 @@
     </section>
     <section class="page">
       <div>
-        <img src="./分解.png" alt="" />
+        <img src="./分解.png" alt=""/>
         <div>分解(组合)</div>
       </div>
     </section>
@@ -201,7 +201,7 @@
     </section>
     <section class="page">
       <div>
-        <img src="./好的分解和坏的分解.png" alt="" />
+        <img src="./好的分解和坏的分解.png" alt=""/>
         <div>好的分解和坏的分解</div>
       </div>
     </section>
@@ -213,21 +213,17 @@ import Hljs from '@/utils/highlight'
 import 'highlight.js/styles/idea.css'
 
 export default {
-  data() {
+  data () {
     return {
       showMode: true,
       milestones: [],
       animating: false
     }
   },
-  mounted() {
+  mounted () {
     this.highlightCode()
     const handleResize = () => {
-      if (window.innerWidth < 700) {
-        this.showMode = false
-      } else {
-        this.showMode = true
-      }
+      this.showMode = window.innerWidth >= 700
 
       const pages = document.getElementsByClassName('page')
       pages.forEach(page => {
@@ -251,17 +247,17 @@ export default {
     }
     window.addEventListener('keydown', handleSpace)
   },
-  updated() {
+  updated () {
     this.highlightCode()
   },
   methods: {
-    highlightCode() {
+    highlightCode () {
       const preEl = document.querySelectorAll('.code')
       preEl.forEach(el => {
         Hljs.highlightBlock(el)
       })
     },
-    nextPage() {
+    nextPage () {
       const top = this.getCurrentScrollTop()
       this.milestones.some(milestone => {
         if (top < milestone - 10) {
@@ -272,7 +268,7 @@ export default {
         }
       })
     },
-    lastPage() {
+    lastPage () {
       const currentPosition = this.getCurrentScrollTop()
       let target = currentPosition
       this.milestones.some(milestone => {
@@ -286,10 +282,10 @@ export default {
         window.scrollTo(0, position)
       )
     },
-    getCurrentScrollTop() {
+    getCurrentScrollTop () {
       return document.documentElement.scrollTop || document.body.scrollTop
     },
-    scrollToY(start, end, rate, callback) {
+    scrollToY (start, end, rate, callback) {
       this.animating = true
 
       let step = () => {
@@ -310,8 +306,8 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/reset.scss';
-@import '@/common/slide/slide.scss';
-@import '@/common/slide/page.scss';
-@import '@/common/slide/item.scss';
+@import '~@/common/reset.scss';
+@import '~@/common/slide/slide.scss';
+@import '~@/common/slide/page.scss';
+@import '~@/common/slide/item.scss';
 </style>

+ 1 - 1
src/server/course.js

@@ -3,7 +3,7 @@ import {
 } from '@/config/server-info.js'
 import axios from 'axios'
 
-export function getTeacherCourse() {
+export function getTeacherCourse () {
   return axios.get(useCourseServer('teacher')).then(res => {
     if (res.data.code === 200) {
       return res.data.data

+ 4 - 4
src/server/slide.js

@@ -3,7 +3,7 @@ import {
 } from '@/config/server-info.js'
 import axios from 'axios'
 
-export function teacherGetSlideById(id) {
+export function teacherGetSlideById (id) {
   return axios.get(useSlideServer('teacher/' + id)).then(res => {
     if (res.data.code === 200) {
       return res.data.data
@@ -11,7 +11,7 @@ export function teacherGetSlideById(id) {
   })
 }
 
-export function teacherGetRecentSlides() {
+export function teacherGetRecentSlides () {
   return axios.get(useSlideServer('teacher'), {
     params: {
       sort: 'updateTime,desc'
@@ -23,7 +23,7 @@ export function teacherGetRecentSlides() {
   })
 }
 
-export function createSlide(courseId, name) {
+export function createSlide (courseId, name) {
   const data = {
     courseId,
     name,
@@ -40,7 +40,7 @@ export function createSlide(courseId, name) {
   })
 }
 
-export function updateSlide(slideInfo, items) {
+export function updateSlide (slideInfo, items) {
   const data = {
     ...slideInfo,
     items: items

+ 10 - 10
src/store/modules/editor.js

@@ -21,14 +21,14 @@ export default {
   },
 
   mutations: {
-    [INIT_BY_STATE](state, payload) {
+    [INIT_BY_STATE] (state, payload) {
       console.log(payload)
       state.items = [...payload.items]
       state.slideInfo = {
         ...payload
       }
     },
-    [INIT_BY_DEFAULT](state, payload) {
+    [INIT_BY_DEFAULT] (state, payload) {
       const newItemId = uuid.v4()
       state.items = [{
         frontendId: newItemId,
@@ -43,7 +43,7 @@ export default {
         ...payload
       }
     },
-    [ADD_ITEM_AFTER](state, payload) {
+    [ADD_ITEM_AFTER] (state, payload) {
       const index = state.items.indexOf(state.items.filter(item => item.frontendId === payload.frontendId)[0])
 
       state.items = [
@@ -55,7 +55,7 @@ export default {
         ...state.items.slice(index + 1)
       ]
     },
-    [MODIFY_ITEM](state, payload) {
+    [MODIFY_ITEM] (state, payload) {
       state.items = [...state.items.map(item => {
         if (item.frontendId === payload.frontendId) {
           return {
@@ -67,16 +67,16 @@ export default {
         }
       })]
     },
-    [DELETE_ITEM](state, payload) {
+    [DELETE_ITEM] (state, payload) {
       state.items = [...state.items.filter((item, index) => index === 0 || item.frontendId !== payload.frontendId)]
     },
-    [SET_FOCUS](state, payload) {
+    [SET_FOCUS] (state, payload) {
       state.focus = {
         ...state.focus,
         ...payload.diff
       }
     },
-    [SET_FOCUS_AFTER](state, payload) {
+    [SET_FOCUS_AFTER] (state, payload) {
       let focusId = ''
       let tagetedFlag = false
       const isHit = state.items.some(item => {
@@ -99,7 +99,7 @@ export default {
         // todo warn
       }
     },
-    [SET_FOCUS_BEFORE](state, payload) {
+    [SET_FOCUS_BEFORE] (state, payload) {
       let focusId = ''
       let tagetedFlag = false
       const isHit = [...state.items].reverse().some(item => {
@@ -122,10 +122,10 @@ export default {
         // todo warn
       }
     },
-    [USE_FOCUS](state, payload) {
+    [USE_FOCUS] (state, payload) {
       state.focus = null
     },
-    [DIFF](state, payload) {
+    [DIFF] (state, payload) {
       const getIdByFrontendId = frontendId => {
         const item = payload.items.filter(item => item.frontendId === frontendId)[0]
         return item.id

+ 1 - 1
src/store/modules/reader.js

@@ -9,7 +9,7 @@ export default {
   },
 
   mutations: {
-    [READER_INIT](state, payload) {
+    [READER_INIT] (state, payload) {
       console.log(payload)
       state.items = [...payload.items]
       state.slideInfo = {

+ 13 - 13
src/utils/default-markdown-fragment.js

@@ -1,14 +1,14 @@
-const defaultMarkdownFagment = {}
-defaultMarkdownFagment.div = ''
-defaultMarkdownFagment.h1 = '# '
-defaultMarkdownFagment.h2 = '## '
-defaultMarkdownFagment.h3 = '### '
-defaultMarkdownFagment.h4 = '#### '
-defaultMarkdownFagment.h5 = '#####'
-defaultMarkdownFagment.h6 = '######'
-defaultMarkdownFagment.blockquote = '> '
-defaultMarkdownFagment.olli = '1. '
-defaultMarkdownFagment.ulli = '- '
-defaultMarkdownFagment.slideBreak = '===='
+const defaultMarkdownFragment = {}
+defaultMarkdownFragment.div = ''
+defaultMarkdownFragment.h1 = '# '
+defaultMarkdownFragment.h2 = '## '
+defaultMarkdownFragment.h3 = '### '
+defaultMarkdownFragment.h4 = '#### '
+defaultMarkdownFragment.h5 = '#####'
+defaultMarkdownFragment.h6 = '######'
+defaultMarkdownFragment.blockquote = '> '
+defaultMarkdownFragment.olli = '1. '
+defaultMarkdownFragment.ulli = '- '
+defaultMarkdownFragment.slideBreak = '===='
 
-export default defaultMarkdownFagment
+export default defaultMarkdownFragment

+ 9 - 5
src/views/Home.vue

@@ -1,10 +1,14 @@
 <template>
   <div>
-    调试链接:<br />
-    <router-link to="/typography">排版布局原型</router-link><br />
-    <router-link to="/teacher">教师主页</router-link><br />
-    <router-link to="/student">学生主页</router-link> <br />
-    <router-link to="/reader/1">阅读器🔗</router-link><br />
+    调试链接:<br/>
+    <router-link to="/typography">排版布局原型</router-link>
+    <br/>
+    <router-link to="/teacher">教师主页</router-link>
+    <br/>
+    <router-link to="/student">学生主页</router-link>
+    <br/>
+    <router-link to="/reader/1">阅读器🔗</router-link>
+    <br/>
   </div>
 </template>
 

+ 4 - 4
src/views/editor/EditorView.vue

@@ -13,19 +13,19 @@ import { mapState } from 'vuex'
 
 export default {
   components: { EditorVue },
-  data() {
+  data () {
     return {
       slideId: this.$route.params.id
     }
   },
-  created() {
+  created () {
     teacherGetSlideById(this.slideId).then(res => {
       this.$store.commit(INIT_BY_STATE, res)
     })
   },
-  mounted() {},
+  mounted () {},
   methods: {
-    save() {
+    save () {
       updateSlide(
         this.$store.state.editor.slideInfo,
         this.$store.state.editor.items

+ 15 - 13
src/views/editor/components/EditableItem.vue

@@ -25,33 +25,33 @@ import {
   SET_FOCUS
 } from '@/store/types/editor-types'
 import defaultPlaceholder from '@/utils/default-placeholder'
-import defaultMarkdownFagment from '@/utils/default-markdown-fragment'
+import defaultMarkdownFragment from '@/utils/default-markdown-fragment'
 import { matchType, generateShowInfo } from '@/utils/item-common'
 
 export default {
   name: 'editable-item',
   props: ['item'],
-  data: function() {
+  data: function () {
     return {
       isCompositionStarted: false,
       range: null,
       type: 'div'
     }
   },
-  mounted() {
+  mounted () {
     this.type = this.matchType(this.item.content)
   },
-  updated() {
+  updated () {
     this.type = this.matchType(this.item.content)
   },
   computed: {
-    showInfo() {
+    showInfo () {
       return generateShowInfo(this.type, this.item)
     }
   },
   methods: {
     matchType,
-    handleKeyDown(e) {
+    handleKeyDown (e) {
       if (!this.isCompositionStarted) {
         switch (e.key) {
           case 'Enter':
@@ -118,19 +118,19 @@ export default {
         }
       }
     },
-    handleCompositionStart() {
+    handleCompositionStart () {
       this.isCompositionStarted = true
     },
-    handleCompositionEnd(e) {
+    handleCompositionEnd (e) {
       this.isCompositionStarted = false
       this.handleInputValue(e)
     },
-    handleInput(e) {
+    handleInput (e) {
       !this.isCompositionStarted && this.handleInputValue(e)
     },
-    handleInputValue(e) {
+    handleInputValue (e) {
       const diff = {
-        content: defaultMarkdownFagment[this.type] + e.target.textContent
+        content: defaultMarkdownFragment[this.type] + e.target.textContent
       }
       if (this.type === 'div' && this.matchType(diff.content) !== this.type) {
         diff.placeholder = defaultPlaceholder[this.matchType(diff.content)]
@@ -157,7 +157,7 @@ export default {
         })
       }
     },
-    handleRangeChanged(cb) {
+    handleRangeChanged (cb) {
       let range = window.getSelection().getRangeAt(0)
       const firstOffset = range.startOffset
       console.log(range)
@@ -176,7 +176,8 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/slide/item.scss';
+@import '~@/common/slide/item.scss';
+
 * [contenteditable] {
   outline: none;
   width: 100%;
@@ -194,6 +195,7 @@ export default {
     color: #bbb;
   }
 }
+
 .slideBreak {
   color: lightblue;
 

+ 3 - 2
src/views/editor/components/EditingPage.vue

@@ -2,7 +2,7 @@
   <section class="page">
     <div>
       <template v-for="item in page.items">
-        <editable-item-vue :item="item" :key="item.frontendId" />
+        <editable-item-vue :item="item" :key="item.frontendId"/>
       </template>
     </div>
   </section>
@@ -10,6 +10,7 @@
 
 <script>
 import EditableItemVue from './EditableItem.vue'
+
 export default {
   name: 'editing-page',
   props: ['page'],
@@ -20,5 +21,5 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/slide/page.scss'
+@import '~@/common/slide/page.scss';
 </style>

+ 8 - 8
src/views/editor/components/Editor.vue

@@ -22,7 +22,7 @@ export default {
     ...mapState({
       items: state => state.editor.items
     }),
-    pages() {
+    pages () {
       const items = this.$store.state.editor.items
       if (items.length === 0) {
         this.$nextTick(() => {
@@ -35,17 +35,17 @@ export default {
 
       return generatePages(items)
     },
-    focus() {
+    focus () {
       const res = this.$store.state.editor.focus
       res !== null &&
-        this.$nextTick(() => {
-          this.checkFocus()
-        })
+      this.$nextTick(() => {
+        this.checkFocus()
+      })
       return this.$store.state.editor.focus
     }
   },
   methods: {
-    checkFocus() {
+    checkFocus () {
       if (this.focus !== null) {
         if (this.focus.focusId) {
           this.$nextTick(() => {
@@ -61,7 +61,7 @@ export default {
         }
       }
     },
-    computeContainerAndOffset(item, offset) {
+    computeContainerAndOffset (item, offset) {
       // todo test
       if (offset === 0) {
         return { container: item, offset: 0 }
@@ -92,5 +92,5 @@ export default {
 }
 </script>
 <style lang="scss" scoped>
-@import '@/common/slide/slide.scss';
+@import '~@/common/slide/slide.scss';
 </style>

+ 2 - 2
src/views/reader/ReaderView.vue

@@ -9,13 +9,13 @@ import { READER_INIT } from '@/store/types/reader-types'
 
 export default {
   components: { ReaderVue },
-  data() {
+  data () {
     return {
       slideId: this.$route.params.id,
       slide: null
     }
   },
-  created() {
+  created () {
     teacherGetSlideById(this.slideId).then(res => {
       this.$store.commit(READER_INIT, res)
     })

+ 5 - 3
src/views/reader/components/Reader.vue

@@ -47,12 +47,12 @@ export default {
     ...mapState({
       items: state => state.reader.items
     }),
-    pages() {
+    pages () {
       return generatePages(this.$store.state.reader.items)
     }
   },
   methods: {
-    handleChangeMode(mode) {
+    handleChangeMode (mode) {
       // todo
     }
   }
@@ -60,7 +60,8 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/slide/slide.scss';
+@import '~@/common/slide/slide.scss';
+
 .tools-top,
 .tools-bottom {
   width: 100vw;
@@ -82,6 +83,7 @@ export default {
   flex: 1;
   max-width: 12px;
 }
+
 .discuss-button-large {
   position: fixed;
   right: 24px;

+ 1 - 1
src/views/reader/components/ReaderItem.vue

@@ -36,7 +36,7 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/slide/item.scss';
+@import '~@/common/slide/item.scss';
 * [contenteditable] {
   outline: none;
   width: 100%;

+ 3 - 2
src/views/reader/components/ReaderPage.vue

@@ -2,7 +2,7 @@
   <section class="page">
     <div>
       <template v-for="item in page.items">
-        <reader-item-vue :item="item" :key="item.frontendId" />
+        <reader-item-vue :item="item" :key="item.frontendId"/>
       </template>
     </div>
   </section>
@@ -10,6 +10,7 @@
 
 <script>
 import ReaderItemVue from './ReaderItem.vue'
+
 export default {
   name: 'editing-page',
   props: ['page'],
@@ -20,5 +21,5 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/slide/page.scss';
+@import '~@/common/slide/page.scss';
 </style>

+ 4 - 4
src/views/reader/components/components/DiscussButtonLarge.vue

@@ -8,13 +8,13 @@
 
 <script>
 export default {
-  data() {
+  data () {
     return {
       isActive: false
     }
   },
   methods: {
-    handleClick() {
+    handleClick () {
       this.isActive = !this.isActive
       this.$emit('discuss-mode-change', this.isActive)
     }
@@ -22,7 +22,7 @@ export default {
 }
 </script>
 <style lang="scss" scoped>
-@import '@/common/button-common';
+@import '~@/common/button-common';
 
 button {
   white-space: nowrap;
@@ -31,7 +31,7 @@ button {
   border-radius: 100px;
   margin: 0 24px;
 
-  font-family: 'iconfont';
+  font-family: 'iconfont', sans-serif;
   font-size: 26px;
 
   color: #ffffff;

+ 4 - 2
src/views/reader/components/components/DiscussButtonSmall.vue

@@ -9,10 +9,11 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/button-common';
+@import '~@/common/button-common';
+
 button {
   color: #999;
-  font-family: 'iconfont';
+  font-family: 'iconfont', sans-serif;
   font-weight: bold;
   font-size: 24px;
 
@@ -44,6 +45,7 @@ button {
 
   & > div {
     margin-right: 12px;
+
     &:hover {
       cursor: default;
       color: #3a3a3a;

+ 4 - 2
src/views/reader/components/components/MarkerButton.vue

@@ -9,10 +9,11 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/button-common';
+@import '~@/common/button-common';
+
 button {
   color: #999;
-  font-family: 'iconfont';
+  font-family: 'iconfont', sans-serif;
   font-weight: bold;
   font-size: 24px;
 
@@ -44,6 +45,7 @@ button {
 
   & > div {
     margin-right: 12px;
+
     &:hover {
       cursor: default;
       color: #3a3a3a;

+ 5 - 3
src/views/reader/components/components/ReadModeButtonGroup.vue

@@ -13,7 +13,7 @@
 <script>
 export default {
   props: ['defaultMode'],
-  data() {
+  data () {
     return {
       mode: this.defaultMode,
       buttons: [
@@ -33,7 +33,7 @@ export default {
     }
   },
   methods: {
-    changeMode(value) {
+    changeMode (value) {
       this.mode = value
       this.$emit('change-mode', this.mode)
     }
@@ -42,7 +42,8 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/button-common';
+@import '~@/common/button-common';
+
 button {
   flex: 1;
   display: block;
@@ -91,6 +92,7 @@ button {
     transition: 0.2s cubic-bezier(0, 0.5, 0.5, 1.25);
   }
 }
+
 @media (max-width: 300px) {
   .button-group-wrapper::before {
     width: calc(33.3333% - 3px);

+ 6 - 6
src/views/reader/components/components/ScalePad.vue

@@ -14,7 +14,8 @@ export default {}
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/button-common';
+@import '~@/common/button-common';
+
 .scale-pad-wrapper {
   display: inline-flex;
   align-items: center;
@@ -24,13 +25,11 @@ export default {}
   border-radius: 100px;
   backdrop-filter: saturate(180%) blur(20px);
   background-color: #aaaaaa22;
-  transition: 0.2s background-color;
-
-  font-family: 'iconfont';
+  font-family: 'iconfont', sans-serif;
   font-size: 16px;
   font-weight: bold;
 
-  transition: 0.1s color;
+  transition: 0.1s;
   color: #777;
 
   & > div {
@@ -52,9 +51,10 @@ export default {}
     display: none;
   }
 }
+
 button {
   color: #999;
-  font-family: 'iconfont';
+  font-family: 'iconfont', sans-serif;
   font-weight: bold;
   font-size: 20px;
 

+ 2 - 2
src/views/student/StudentHomeView.vue

@@ -5,7 +5,7 @@
         <icon-link-vue :tab="tab" :key="index"></icon-link-vue>
       </template>
     </template>
-    <template v-slot:preview> </template>
+    <template v-slot:preview></template>
   </role-home-vue>
 </template>
 
@@ -15,7 +15,7 @@ import IconLinkVue from '@/components/IconLink.vue'
 
 export default {
   components: { RoleHomeVue, IconLinkVue },
-  data() {
+  data () {
     return {
       tabs: [
         {

+ 1 - 1
src/views/student/tabs/DiscussionTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 1 - 1
src/views/student/tabs/HistoryTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 1 - 1
src/views/student/tabs/HomeTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 1 - 1
src/views/student/tabs/InfoTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 1 - 1
src/views/student/tabs/PersonalTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 1 - 1
src/views/student/tabs/SearchTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 1 - 1
src/views/teacher/TeacherHomeView.vue

@@ -15,7 +15,7 @@ import IconLinkVue from '@/components/IconLink.vue'
 
 export default {
   components: { RoleHomeVue, IconLinkVue },
-  data() {
+  data () {
     return {
       tabs: [
         {

+ 22 - 17
src/views/teacher/tabs/AddTab.vue

@@ -3,19 +3,23 @@
     <div class="title">新建幻灯片</div>
     <div class="sub-title">所属课程:</div>
     <div class="select-wrapper">
-      <select v-model="selectedCourseId">
-        <option disabled value="">[ 未填写 ]</option>
-        <option v-for="course of courses" :value="course.id" :key="course.id">
-          {{ course.name }}
-        </option>
-      </select>
+      <label>
+        <select v-model="selectedCourseId">
+          <option disabled value="">[ 未填写 ]</option>
+          <option v-for="course of courses" :value="course.id" :key="course.id">
+            {{ course.name }}
+          </option>
+        </select>
+      </label>
     </div>
     <div class="sub-title">幻灯片名称:</div>
-    <input
-      type="text"
-      v-model="userInput"
-      placeholder="请勿与同课程幻灯片重名"
-    />
+    <label>
+      <input
+        type="text"
+        v-model="userInput"
+        placeholder="请勿与同课程幻灯片重名"
+      />
+    </label>
     <button class="my-button" @click.prevent="handleSubmit">
       添加
     </button>
@@ -25,21 +29,22 @@
 <script>
 import { getTeacherCourse } from '@/server/course'
 import { createSlide } from '@/server/slide'
+
 export default {
-  data() {
+  data () {
     return {
       courses: [],
       selectedCourseId: '',
       userInput: ''
     }
   },
-  mounted() {
+  mounted () {
     getTeacherCourse().then(res => {
       this.courses = res
     })
   },
   methods: {
-    handleSubmit() {
+    handleSubmit () {
       createSlide(this.selectedCourseId, this.userInput).then(res => {
         this.$router.push('/editor/' + res.id)
       })
@@ -48,7 +53,8 @@ export default {
 }
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
+
 $input-background-color: #ebf0f5;
 
 .title {
@@ -74,8 +80,7 @@ input {
   width: 100%;
   height: 48px;
   line-height: 40px;
-  padding: 0;
-  padding-left: 12px;
+  padding: 0 0 0 12px;
 }
 
 select {

+ 1 - 1
src/views/teacher/tabs/DiscussionTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 5 - 3
src/views/teacher/tabs/HomeTab.vue

@@ -28,12 +28,12 @@ import SlideListItemVue from '@/components/SlideListItem.vue'
 import { teacherGetRecentSlides } from '@/server/slide'
 
 export default {
-  data() {
+  data () {
     return {
       recentSlides: []
     }
   },
-  mounted() {
+  mounted () {
     teacherGetRecentSlides().then(res => {
       this.recentSlides = res
     })
@@ -42,11 +42,13 @@ export default {
 }
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
+
 .tab-wrapper {
   max-height: 80vh;
   overflow: auto;
 }
+
 .recent-slides-section {
   max-height: 50vh;
   overflow: auto;

+ 1 - 1
src/views/teacher/tabs/InfoTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 1 - 1
src/views/teacher/tabs/PersonalTab.vue

@@ -8,5 +8,5 @@
 export default {}
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
 </style>

+ 5 - 3
src/views/teacher/tabs/SearchTab.vue

@@ -5,14 +5,15 @@
     <div v-if="!searchKey" class="tip">
       请输入关键字查询
     </div>
-    <template v-else> </template>
+    <template v-else></template>
   </div>
 </template>
 
 <script>
 import SearchBarVue from '@/components/SearchBar'
+
 export default {
-  data() {
+  data () {
     return {
       searchKey: ''
     }
@@ -21,7 +22,8 @@ export default {
 }
 </script>
 <style lang="scss" scoped>
-@import '@/common/tab-common.scss';
+@import '~@/common/tab-common.scss';
+
 .tip {
   color: #aabaca;
   font-size: 20px;