Selaa lähdekoodia

refactor: 抽离教师主页组件、样式,重新整理所有样式文件

ChenYangfan 6 vuotta sitten
vanhempi
commit
d015388471

+ 11 - 1
src/App.vue

@@ -15,5 +15,15 @@ body {
 }
 </style>
 
-<style lang="scss" scoped>
+<style lang="scss">
+@font-face {
+  font-family: 'iconfont'; /* project id 1598214 */
+  src: url('//at.alicdn.com/t/font_1598214_il2if4ux43.eot');
+  src: url('//at.alicdn.com/t/font_1598214_il2if4ux43.eot?#iefix')
+      format('embedded-opentype'),
+    url('//at.alicdn.com/t/font_1598214_il2if4ux43.woff2') format('woff2'),
+    url('//at.alicdn.com/t/font_1598214_il2if4ux43.woff') format('woff'),
+    url('//at.alicdn.com/t/font_1598214_il2if4ux43.ttf') format('truetype'),
+    url('//at.alicdn.com/t/font_1598214_il2if4ux43.svg#iconfont') format('svg');
+}
 </style>

+ 0 - 187
src/common/mode-common.scss

@@ -1,187 +0,0 @@
-.page {
-  display: flex;
-  flex-wrap: wrap;
-
-  margin: 0 auto;
-  align-items: center;
-
-  padding: 0 2rem;
-
-  box-sizing: border-box;
-  font-weight: 500;
-
-  &>div {
-    width: 100%;
-    box-sizing: border-box;
-  }
-}
-
-.slide {
-  box-sizing: border-box;
-  text-align: justify;
-  margin: 0 auto;
-  outline: none;
-
-  line-height: 1.6;
-
-  font-size: 24px;
-
-  h1,
-  h2,
-  h3,
-  h4,
-  h5,
-  h6 {
-    font-weight: 600;
-    width: 100%;
-  }
-
-  h1 {
-    font-size: 2em;
-    margin: 1em 0 0.35em 0;
-  }
-
-  h2 {
-    font-size: 1.8em;
-    margin: 1em 0 0.3em 0;
-  }
-
-  h3 {
-    font-size: 1.5em;
-    margin: .5em 0 0.2em 0;
-  }
-
-  h4 {
-    font-size: 1.35em;
-    margin: .5em 0 0.2em 0;
-  }
-
-  h5 {
-    font-size: 1.2em;
-    margin: .25em 0 0.1em 0;
-  }
-
-  h6 {
-    font-size: 1.1em;
-    margin: .25em 0 0.1em 0;
-  }
-
-  p {
-    margin: 0.44em 0;
-  }
-
-  li {
-    margin: 0.19em;
-  }
-
-  ul,
-  ol {
-    list-style: none;
-    padding-left: 1em;
-    margin-top: 0.3em;
-    margin-bottom: 0.8em;
-  }
-
-  ul>li::before {
-    content: '\02022';
-    display: inline-block;
-    color: #1976d2;
-    width: 1em;
-    margin-left: -1em;
-  }
-
-  ol {
-    counter-reset: li;
-    margin: 0 0 0 0.5em;
-
-    li {
-      text-align: left;
-    }
-  }
-
-  ol>li::before {
-    font-family: 'Courier', 'Courier New', monospace !important;
-    overflow: hidden;
-    font-size: 1em;
-    line-height: 0;
-    content: counter(li) '.';
-    color: #1976d2;
-    display: inline;
-    margin-left: -1.6em;
-    margin-right: 0.4em;
-    text-align: right;
-    counter-increment: li;
-  }
-
-  blockquote {
-    margin: 1em 0;
-    font-family: serif;
-    font-size: 1.5em;
-    position: relative;
-    font-style: italic;
-    width: 100%;
-    font-weight: 600;
-
-
-    &::before {
-      content: '"';
-      position: absolute;
-      transform: translateX(-150%);
-    }
-
-    &::after {
-      content: '"';
-      position: absolute;
-      transform: translateX(150%);
-    }
-  }
-
-  a {
-    text-decoration: underline solid transparent;
-    transition: 0.2s all ease-out;
-
-    &:hover {
-      text-decoration: underline solid #ccc;
-    }
-  }
-
-  li>a,
-  p>a {
-    color: #1976d2;
-  }
-
-  img {
-    max-width: 100%;
-    max-height: 100vh;
-    margin: 0.94em auto 1.88em auto;
-    display: block;
-    box-shadow: 0 0.13em 0.63em 0 #e5e5e5;
-  }
-
-  .code {
-
-    font-family: monospace;
-    font-weight: bold;
-    text-align: left;
-    word-break: break-all;
-
-    line-height: 2;
-    display: block;
-    padding: 10px 15px;
-    border: gray 1px solid;
-  }
-
-  code {
-    width: 100%;
-    overflow: auto;
-    padding: 0 0.19em;
-    font-size: 0.8em;
-    font-weight: blod;
-  }
-}
-
-@media (min-width: 900px) {
-  .slide {
-    padding: 0 10vw;
-  }
-}

+ 0 - 8
src/common/read-mode.scss

@@ -1,8 +0,0 @@
-.read-mode {
-  .page {
-    min-height: unset;
-    padding-top: 20px;
-    padding-bottom: 20px;
-    font-size: 1rem;
-  }
-}

+ 4 - 0
src/common/readme.md

@@ -0,0 +1,4 @@
+# 关于这些公共样式文件的说明:
+
+### 幻灯片样式
+幻灯片样式由于存在放映模式、编辑模式,各种模式中都存在各级组件,因此将样式按组件粒度进行编写有助于减少最终代码的体积

+ 0 - 10
src/common/show-mode.scss

@@ -1,10 +0,0 @@
-.show-mode {
-  .page {
-    min-height: 100vh;
-  }
-
-  code {
-    font-weight: 800;
-    font-size: 1em
-  }
-}

+ 143 - 0
src/common/slide/item.scss

@@ -0,0 +1,143 @@
+@import './../theme.scss';
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-weight: 600;
+  width: 100%;
+}
+
+
+h1 {
+  font-size: 2em;
+  margin: 1em 0 0.35em 0;
+}
+
+h2 {
+  font-size: 1.8em;
+  margin: 1em 0 0.3em 0;
+}
+
+h3 {
+  font-size: 1.5em;
+  margin: .5em 0 0.2em 0;
+}
+
+h4 {
+  font-size: 1.35em;
+  margin: .5em 0 0.2em 0;
+}
+
+h5 {
+  font-size: 1.2em;
+  margin: .25em 0 0.1em 0;
+}
+
+h6 {
+  font-size: 1.1em;
+  margin: .25em 0 0.1em 0;
+}
+
+p,
+div {
+  margin: 0.44em 0;
+}
+
+li {
+  margin: 0.19em;
+}
+
+ul,
+ol {
+  list-style: none;
+  padding-left: 1em;
+  margin-top: 0.3em;
+  margin-bottom: 0.8em;
+}
+
+ul>li::before {
+  content: '\02022';
+  display: inline-block;
+  color: $theme-blue;
+  width: 1em;
+  margin-left: -1em;
+}
+
+ol {
+  counter-reset: li;
+  margin: 0 0 0 0.5em;
+
+  li {
+    text-align: left;
+  }
+}
+
+ol>li::before {
+  font-family: 'Courier', 'Courier New', monospace !important;
+  overflow: hidden;
+  font-size: 1em;
+  line-height: 0;
+  content: counter(li) '.';
+  color: $theme-blue;
+   display: inline;
+  margin-left: -1.6em;
+  margin-right: 0.4em;
+  text-align: right;
+  counter-increment: li;
+}
+
+blockquote {
+  margin: 1em 0;
+  font-family: serif;
+  font-size: 1.5em;
+  position: relative;
+  font-style: italic;
+  width: 100%;
+  font-weight: 600;
+}
+
+a {
+  text-decoration: underline solid transparent;
+  transition: 0.2s all ease-out;
+
+  &:hover {
+    text-decoration: underline solid #ccc;
+  }
+}
+
+li>a,
+p>a {
+  color: #1976d2;
+}
+
+img {
+  max-width: 100%;
+  max-height: 100vh;
+  margin: 0.94em auto 1.88em auto;
+  display: block;
+  box-shadow: 0 0.13em 0.63em 0 #e5e5e5;
+}
+
+.code {
+
+  font-family: monospace;
+  font-weight: bold;
+  text-align: left;
+  word-break: break-all;
+
+  line-height: 2;
+  display: block;
+  padding: 10px 15px;
+  border: gray 1px solid;
+}
+
+code {
+  width: 100%;
+  overflow: auto;
+  padding: 0 0.19em;
+  font-size: 0.8em;
+  font-weight: blod;
+}

+ 37 - 0
src/common/slide/page.scss

@@ -0,0 +1,37 @@
+.page {
+  display: flex;
+  flex-wrap: wrap;
+
+  margin: 0 auto;
+  align-items: center;
+
+  padding: 0 2rem;
+
+  box-sizing: border-box;
+  font-weight: 500;
+
+  &>div {
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+
+.read-mode {
+  .page {
+    min-height: unset;
+    padding-top: 20px;
+    padding-bottom: 20px;
+    font-size: 1rem;
+  }
+}
+
+.show-mode {
+  .page {
+    min-height: 100vh;
+  }
+
+  code {
+    font-weight: 800;
+    font-size: 1em
+  }
+}

+ 18 - 0
src/common/slide/slide.scss

@@ -0,0 +1,18 @@
+.slide {
+  box-sizing: border-box;
+  text-align: justify;
+  margin: 0 auto;
+  outline: none;
+  width: 1100px;
+
+  line-height: 1.6;
+
+  font-size: 24px;
+
+
+  @media (min-width: 900px) {
+    .slide {
+      padding: 0 10vw;
+    }
+  }
+}

+ 4 - 0
src/common/theme.scss

@@ -0,0 +1,4 @@
+$theme-blue: #5485e5;
+
+$icon-normal-color: #7a8a9a;
+$icon-hover-color: lighten($theme-blue, 10);

+ 1 - 2
src/components/editor/EditableItem.vue

@@ -212,10 +212,9 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '@/common/mode-common.scss';
+@import '@/common/slide/item.scss';
 * [contenteditable] {
   outline: none;
-  padding: 8px 2px;
   width: 100%;
 
   &:hover {

+ 1 - 4
src/components/editor/EditingPage.vue

@@ -20,8 +20,5 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.page > div {
-  width: 100%;
-  box-sizing: border-box;
-}
+@import '@/common/slide/page.scss'
 </style>

+ 1 - 6
src/components/editor/Editor.vue

@@ -95,8 +95,6 @@ export default {
         return { container: item, offset: 0 }
       }
 
-      // default return value is the end of this element
-      // notice that when the element is not Text, offset 1 means the end of element
       return {
         container: item,
         offset: 1
@@ -106,8 +104,5 @@ export default {
 }
 </script>
 <style lang="scss" scoped>
-@import '@/common/reset.scss';
-@import '@/common/mode-common.scss';
-@import '@/common/show-mode.scss';
-@import '@/common/read-mode.scss';
+@import '@/common/slide/slide.scss';
 </style>

+ 53 - 0
src/components/home/IconLink.vue

@@ -0,0 +1,53 @@
+<template>
+  <router-link :to="tab.name">
+    <div class="icon" :class="currentRouteName === tab.name ? 'active' : ''">
+      {{ tab.unicode }}
+    </div>
+  </router-link>
+</template>
+
+<script>
+export default {
+  props: ['tab'],
+  data() {
+    return {
+      currentRouteName: this.$route.name
+    }
+  },
+  watch: {
+    $route() {
+      this.currentRouteName = this.$route.name
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '@/common/theme.scss';
+
+.tab {
+  margin: -12px 0;
+  a {
+    outline: none;
+    text-decoration: none;
+    color: black;
+  }
+  .icon {
+    user-select: none;
+    cursor: pointer;
+    padding: 12px 0;
+    text-align: center;
+    font-family: 'iconfont';
+    font-size: 34px;
+    color: $icon-normal-color;
+    transition: color .1s ease-out;
+
+    &:hover {
+      color: $icon-hover-color;
+    }
+  }
+  .active {
+    color: $theme-blue;
+  }
+}
+</style>

+ 0 - 0
src/components/teacher/SlideListItem.vue → src/components/home/SlideListItem.vue


+ 56 - 0
src/layouts/RoleHome.vue

@@ -0,0 +1,56 @@
+<template>
+  <div class="main-container">
+    <div class="menu-container">
+      <div class="tab-container">
+        <div class="tab">
+          <slot name="tab"></slot>
+        </div>
+      </div>
+      <div class="view-container">
+        <transition name="fade" mode="out-in">
+          <router-view />
+        </transition>
+      </div>
+    </div>
+    <div class="preview-container">
+      <slot name="preview"></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
+
+<style lang="scss" scoped>
+$icon-normal-color: #7a8a9a;
+$icon-active-color: #5485e5;
+$icon-hover-color: rgb(146, 171, 221);
+
+.main-container {
+  height: 100vh;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.menu-container {
+  display: flex;
+}
+.tab-container {
+  padding: 24px 18px 24px 36px;
+  display: flex;
+  flex-direction: row;
+  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;
+}
+</style>

+ 12 - 3
src/prototype/Typography.vue

@@ -85,6 +85,15 @@
         <h2>2. 降低复杂度 - 分解与抽象</h2>
       </div>
     </section>
+    <section class="page">
+      <div>
+        <h2>2. 降低复杂度 - 分解与抽象</h2>
+        <div>分解与抽象</div>
+        <div>分解与抽象</div>
+        <div>分解与抽象</div>
+        <div>分解与抽象</div>
+      </div>
+    </section>
     <section class="page">
       <div>
         <h3>为什么要降低复杂度</h3>
@@ -302,7 +311,7 @@ export default {
 
 <style lang="scss" scoped>
 @import '@/common/reset.scss';
-@import '@/common/mode-common.scss';
-@import '@/common/read-mode.scss';
-@import '@/common/show-mode.scss';
+@import '@/common/slide/slide.scss';
+@import '@/common/slide/page.scss';
+@import '@/common/slide/item.scss';
 </style>

+ 2 - 2
src/views/Home.vue

@@ -1,8 +1,8 @@
 <template>
   <div>
     调试链接:<br />
-    1. <router-link to="/editor/123123">编辑器</router-link> 2.
-    <router-link to="/typography">排版布局原型</router-link>3.
+    <router-link to="/typography">排版布局原型</router-link>
+    <br />
     <router-link to="/teacher">教师主页</router-link>
   </div>
 </template>

+ 1 - 0
src/views/editor/EditorView.vue

@@ -24,6 +24,7 @@ export default {
       this.$store.commit(INIT_BY_STATE, res)
     })
   },
+  mounted() {},
   methods: {
     save() {
       updateSlide(

+ 38 - 130
src/views/teacher/TeacherHomeView.vue

@@ -1,144 +1,52 @@
 <template>
-  <div class="main-container">
-    <div class="menu-container">
-      <div class="tab-container">
-        <div class="tab">
-          <router-link to="teacher-home">
-            <div
-              class="icon"
-              :class="currentRouteName === 'teacher-home' ? 'active' : ''"
-            >
-              &#xe68b;
-            </div>
-          </router-link>
-          <router-link to="teacher-search">
-            <div
-              class="icon"
-              :class="currentRouteName === 'teacher-search' ? 'active' : ''"
-            >
-              &#xe6a2;
-            </div>
-          </router-link>
-          <router-link to="teacher-add">
-            <div
-              class="icon"
-              :class="currentRouteName === 'teacher-add' ? 'active' : ''"
-            >
-              &#xe71b;
-            </div>
-          </router-link>
-          <router-link to="teacher-personal">
-            <div
-              class="icon"
-              :class="currentRouteName === 'teacher-personal' ? 'active' : ''"
-            >
-              &#xe790;
-            </div>
-          </router-link>
-          <router-link to="teacher-feedback">
-            <div
-              class="icon"
-              :class="currentRouteName === 'teacher-feedback' ? 'active' : ''"
-            >
-              &#xe68a;
-            </div>
-          </router-link>
-          <div class="line"></div>
-          <router-link to="teacher-info">
-            <div
-              class="icon"
-              :class="currentRouteName === 'teacher-info' ? 'active' : ''"
-            >
-              &#xe68e;
-            </div>
-          </router-link>
-        </div>
-      </div>
-      <div class="view-container">
-        <transition name="fade" mode="out-in">
-          <router-view />
-        </transition>
-      </div>
-    </div>
-    <div class="preview-container"></div>
-  </div>
+  <role-home-vue>
+    <template v-slot:tab>
+      <template v-for="tab of tabs">
+        <icon-link-vue :tab="tab" :key="tab.name"></icon-link-vue>
+      </template>
+    </template>
+    <template v-slot:preview></template>
+  </role-home-vue>
 </template>
 
 <script>
+import RoleHomeVue from '../../layouts/RoleHome.vue'
+import IconLinkVue from '../../components/home/IconLink.vue'
+
 export default {
+  components: { RoleHomeVue, IconLinkVue },
   data() {
     return {
-      currentRouteName: this.$route.name
-    }
-  },
-  methods: {},
-  watch: {
-    $route() {
-      this.currentRouteName = this.$route.name
+      tabs: [
+        {
+          name: 'teacher-home',
+          unicode: '\ue68b'
+        },
+        {
+          name: 'teacher-search',
+          unicode: '\ue6a2'
+        },
+        {
+          name: 'teacher-add',
+          unicode: '\ue71b'
+        },
+        {
+          name: 'teacher-personal',
+          unicode: '\ue790'
+        },
+        {
+          name: 'teacher-feedback',
+          unicode: '\ue68a'
+        },
+        {
+          name: 'teacher-info',
+          unicode: '\ue68e'
+        }
+      ]
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-$icon-normal-color: #7a8a9a;
-$icon-active-color: #5485e5;
-$icon-hover-color: rgb(146, 171, 221);
-
-@font-face {
-  font-family: 'iconfont'; /* project id 1598214 */
-  src: url('//at.alicdn.com/t/font_1598214_il2if4ux43.eot');
-  src: url('//at.alicdn.com/t/font_1598214_il2if4ux43.eot?#iefix')
-      format('embedded-opentype'),
-    url('//at.alicdn.com/t/font_1598214_il2if4ux43.woff2') format('woff2'),
-    url('//at.alicdn.com/t/font_1598214_il2if4ux43.woff') format('woff'),
-    url('//at.alicdn.com/t/font_1598214_il2if4ux43.ttf') format('truetype'),
-    url('//at.alicdn.com/t/font_1598214_il2if4ux43.svg#iconfont') format('svg');
-}
-.main-container {
-  height: 100vh;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-.menu-container {
-  display: flex;
-}
-.tab-container {
-  padding: 24px 18px 24px 36px;
-  display: flex;
-  flex-direction: row;
-  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;
-  a {
-    outline: none;
-    text-decoration: none;
-    color: black;
-  }
-  .icon {
-    user-select: none;
-    cursor: pointer;
-    padding: 12px 0;
-    text-align: center;
-    font-family: 'iconfont';
-    font-size: 34px;
-    color: $icon-normal-color;
-  }
-  .active {
-    color: $icon-active-color;
-  }
-}
 </style>

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

@@ -4,7 +4,7 @@
     <div class="sub-title">所属课程:</div>
     <div class="select-wrapper">
       <select v-model="selectedCourseId">
-        <option value="">[ 未填写 ]</option>
+        <option disabled value="">[ 未填写 ]</option>
         <option v-for="course of courses" :value="course.id" :key="course.id">
           {{ course.name }}
         </option>

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

@@ -24,7 +24,7 @@
 </template>
 
 <script>
-import SlideListItemVue from '@/components/teacher/SlideListItem.vue'
+import SlideListItemVue from '@/components/home/SlideListItem.vue'
 import { teacherGetRecentSlides } from '../../../server/slide'
 
 export default {

+ 3 - 1
src/views/teacher/tabs/tab-common.scss

@@ -1,3 +1,5 @@
+@import '@/common/theme.scss';
+
 .tab-wrapper {
   width: 320px;
   margin: auto;
@@ -17,7 +19,7 @@
   margin-bottom: 16px;
 }
 
-$submit-button-color: #5485e5;
+$submit-button-color: $theme-blue;
 
 .my-button {
   display: block;