离校前端框架,包括数据字典、工作队伍、新闻公告模块
diff --git a/leave-school-vue/src/components/Breadcrumb/index.vue b/leave-school-vue/src/components/Breadcrumb/index.vue
new file mode 100644
index 0000000..a1da13b
--- /dev/null
+++ b/leave-school-vue/src/components/Breadcrumb/index.vue
@@ -0,0 +1,51 @@
+<template>
+  <el-breadcrumb class="app-breadcrumb" separator="/">
+    <transition-group name="breadcrumb">
+      <el-breadcrumb-item v-for="(item,index)  in levelList" :key="item.path" v-if="item.meta.title">
+        <span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{item.meta.title}}</span>
+        <router-link v-else :to="item.redirect||item.path">{{item.meta.title}}</router-link>
+      </el-breadcrumb-item>
+    </transition-group>
+  </el-breadcrumb>
+</template>
+
+<script>
+export default {
+  created() {
+    this.getBreadcrumb()
+  },
+  data() {
+    return {
+      levelList: null
+    }
+  },
+  watch: {
+    $route() {
+      this.getBreadcrumb()
+    }
+  },
+  methods: {
+    getBreadcrumb() {
+      let matched = this.$route.matched.filter(item => item.name)
+      const first = matched[0]
+      if (first && first.name !== 'Dashboard') {
+        matched = [{ path: '/dashboard', meta: { title: '离校系统' }}].concat(matched)
+      }
+      this.levelList = matched
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+  .app-breadcrumb.el-breadcrumb {
+    display: inline-block;
+    font-size: 14px;
+    line-height: 50px;
+    margin-left: 10px;
+    .no-redirect {
+      color: #97a8be;
+      cursor: text;
+    }
+  }
+</style>
diff --git a/leave-school-vue/src/components/Hamburger/index.vue b/leave-school-vue/src/components/Hamburger/index.vue
new file mode 100644
index 0000000..fbdf72c
--- /dev/null
+++ b/leave-school-vue/src/components/Hamburger/index.vue
@@ -0,0 +1,44 @@
+<template>
+  <div>
+    <svg t="1492500959545" @click="toggleClick" class="hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
+      version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
+      <path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
+        p-id="1692"></path>
+      <path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
+        p-id="1693"></path>
+      <path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
+        p-id="1694"></path>
+    </svg>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'hamburger',
+  props: {
+    isActive: {
+      type: Boolean,
+      default: false
+    },
+    toggleClick: {
+      type: Function,
+      default: null
+    }
+  }
+}
+</script>
+
+<style scoped>
+.hamburger {
+	display: inline-block;
+	cursor: pointer;
+	width: 20px;
+	height: 20px;
+	transform: rotate(90deg);
+	transition: .38s;
+	transform-origin: 50% 50%;
+}
+.hamburger.is-active {
+	transform: rotate(0deg);
+}
+</style>
diff --git a/leave-school-vue/src/components/ScrollPane/index.vue b/leave-school-vue/src/components/ScrollPane/index.vue
new file mode 100644
index 0000000..1ce68c1
--- /dev/null
+++ b/leave-school-vue/src/components/ScrollPane/index.vue
@@ -0,0 +1,72 @@
+<template>
+  <div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll">
+    <div class="scroll-wrapper" ref="scrollWrapper" :style="{left: left + 'px'}">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+const padding = 15 // tag's padding
+
+export default {
+  name: 'scrollPane',
+  data() {
+    return {
+      left: 0
+    }
+  },
+  methods: {
+    handleScroll(e) {
+      const eventDelta = e.wheelDelta || -e.deltaY * 3
+      const $container = this.$refs.scrollContainer
+      const $containerWidth = $container.offsetWidth
+      const $wrapper = this.$refs.scrollWrapper
+      const $wrapperWidth = $wrapper.offsetWidth
+
+      if (eventDelta > 0) {
+        this.left = Math.min(0, this.left + eventDelta)
+      } else {
+        if ($containerWidth - padding < $wrapperWidth) {
+          if (this.left < -($wrapperWidth - $containerWidth + padding)) {
+            this.left = this.left
+          } else {
+            this.left = Math.max(this.left + eventDelta, $containerWidth - $wrapperWidth - padding)
+          }
+        } else {
+          this.left = 0
+        }
+      }
+    },
+    moveToTarget($target) {
+      const $container = this.$refs.scrollContainer
+      const $containerWidth = $container.offsetWidth
+      const $targetLeft = $target.offsetLeft
+      const $targetWidth = $target.offsetWidth
+
+      if ($targetLeft < -this.left) {
+        // tag in the left
+        this.left = -$targetLeft + padding
+      } else if ($targetLeft + padding > -this.left && $targetLeft + $targetWidth < -this.left + $containerWidth - padding) {
+        // tag in the current view
+        // eslint-disable-line
+      } else {
+        // tag in the right
+        this.left = -($targetLeft - ($containerWidth - $targetWidth) + padding)
+      }
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+.scroll-container {
+  white-space: nowrap;
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+  .scroll-wrapper {
+    position: absolute;
+  }
+}
+</style>
diff --git a/leave-school-vue/src/components/SvgIcon/index.vue b/leave-school-vue/src/components/SvgIcon/index.vue
new file mode 100644
index 0000000..e331a27
--- /dev/null
+++ b/leave-school-vue/src/components/SvgIcon/index.vue
@@ -0,0 +1,42 @@
+<template>
+  <svg :class="svgClass" aria-hidden="true">
+    <use :xlink:href="iconName"></use>
+  </svg>
+</template>
+
+<script>
+export default {
+  name: 'svg-icon',
+  props: {
+    iconClass: {
+      type: String,
+      required: true
+    },
+    className: {
+      type: String
+    }
+  },
+  computed: {
+    iconName() {
+      return `#icon-${this.iconClass}`
+    },
+    svgClass() {
+      if (this.className) {
+        return 'svg-icon ' + this.className
+      } else {
+        return 'svg-icon'
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.svg-icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+</style>
diff --git a/leave-school-vue/src/components/UEditor/index.vue b/leave-school-vue/src/components/UEditor/index.vue
new file mode 100644
index 0000000..6f44fc1
--- /dev/null
+++ b/leave-school-vue/src/components/UEditor/index.vue
@@ -0,0 +1,64 @@
+<template>
+  <div>
+    <script id="editor" type="text/plain"></script>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'UE',
+    data() {
+      return {
+        editor: null,
+        isReady: false,
+        isInit: false
+      }
+    },
+    props: {
+      value: {
+        type: String
+      },
+      config: {
+        type: Object
+      }
+    },
+    mounted() {
+      const _this = this
+      window.UE.delEditor('editor')
+      this.editor = window.UE.getEditor('editor', this.config) // 初始化UE
+      // this.editor.addListener('ready', function() {
+      //   _this.editor.setContent(_this.defaultMsg) // 确保UE加载完成后,放入内容。
+      // })
+      this.editor.ready(() => {
+        _this.setContent(_this.value) // 确保UE加载完成后,放入内容。
+        _this.editor.addListener('contentChange', () => {
+          const content = _this.editor.getContent()
+          _this.$emit('input', content)
+        })
+
+        _this.$emit('ready', this.editor)
+        _this.isReady = true
+      })
+    },
+    methods: {
+      setContent(value) {
+        this.editor.setContent(value || '')
+      },
+      getUEContent() { // 获取内容方法
+        return this.editor.getContent()
+      }
+    },
+    watch: {
+      value(val) {
+        this.setContent(val)
+      }
+    },
+    destroyed() {
+      this.editor.destroy()
+    }
+  }
+</script>
+<style>
+.edui-editor-toolbarbox{
+  line-height:22px
+}
+</style>