离校前端框架,包括数据字典、工作队伍、新闻公告模块
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>