Skip to content

Commit

Permalink
前端添加tag
Browse files Browse the repository at this point in the history
  • Loading branch information
Gsangu committed Apr 10, 2019
1 parent 8f4256d commit fc0d7eb
Show file tree
Hide file tree
Showing 16 changed files with 576 additions and 18 deletions.
27 changes: 23 additions & 4 deletions resources/assets/js/components/Breadcrumb/index.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" v-if="item.meta.title" :key="item.path">
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{ generateTitle(item.meta.title) }}</span>
<router-link v-else :to="item.redirect||item.path">{{ generateTitle(item.meta.title) }}</router-link>
<el-breadcrumb-item v-for="(item,index) in levelList" v-if="item.meta.title&&item.meta.breadcrumb!==false" :key="item.path">
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{
generateTitle(item.meta.title) }}</span>
<a v-else @click.prevent="handleLink(item)">{{ generateTitle(item.meta.title) }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>

<script>
import { generateTitle } from '@/utils/i18n'
import pathToRegexp from 'path-to-regexp'
export default {
data() {
Expand All @@ -29,12 +31,29 @@ export default {
methods: {
generateTitle,
getBreadcrumb() {
let matched = this.$route.matched.filter(item => item.name)
let matched = this.$route.matched.filter(item => {
if (item.name) {
return true
}
})
const first = matched[0]
if (first && first.name.trim().toLocaleLowerCase() !== 'Dashboard'.toLocaleLowerCase()) {
matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
}
this.levelList = matched
},
pathCompile(path) {
const { params } = this.$route
var toPath = pathToRegexp.compile(path)
return toPath(params)
},
handleLink(item) {
const { redirect, path } = item
if (redirect) {
this.$router.push(redirect)
return
}
this.$router.push(this.pathCompile(path))
}
}
}
Expand Down
92 changes: 92 additions & 0 deletions resources/assets/js/components/ScrollPane/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<template>
<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
<slot/>
</el-scrollbar>
</template>

<script>
const tagAndTagSpacing = 4 // tagAndTagSpacing
export default {
name: 'ScrollPane',
data() {
return {
left: 0
}
},
methods: {
handleScroll(e) {
const eventDelta = e.wheelDelta || -e.deltaY * 40
const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
},
moveToTarget(currentTag) {
const $container = this.$refs.scrollContainer.$el
const $containerWidth = $container.offsetWidth
const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
const tagList = this.$parent.$refs.tag
let firstTag = null
let lastTag = null
let prevTag = null
let nextTag = null
// find first tag and last tag
if (tagList.length > 0) {
firstTag = tagList[0]
lastTag = tagList[tagList.length - 1]
}
// find preTag and nextTag
for (let i = 0; i < tagList.length; i++) {
if (tagList[i] === currentTag) {
if (i === 0) {
nextTag = tagList[i].length > 1 && tagList[i + 1]
} else if (i === tagList.length - 1) {
prevTag = tagList[i].length > 1 && tagList[i - 1]
} else {
prevTag = tagList[i - 1]
nextTag = tagList[i + 1]
}
break
}
}
if (firstTag === currentTag) {
$scrollWrapper.scrollLeft = 0
} else if (lastTag === currentTag) {
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
} else {
// the tag's offsetLeft after of nextTag
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
// the tag's offsetLeft before of prevTag
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
}
}
}
}
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.scroll-container {
white-space: nowrap;
position: relative;
overflow: hidden;
width: 100%;
/deep/ {
.el-scrollbar__bar {
bottom: 0px;
}
.el-scrollbar__wrap {
height: 49px;
}
}
}
</style>
34 changes: 32 additions & 2 deletions resources/assets/js/lang/zh.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
export default {
route: {
dashboard: '首页',
school: '校内资源管理',
studentList: '学生信息管理',
teacherList: '教师信息管理',
collegeList: '院系信息管理',
practice: '顶岗实习信息',
manage: '信息管理/导出',
company: '校企合作企业',
instructor: '企业指导教师',
practiceList: '顶岗实习信息',
dataCount: '数据统计',
workSiteCount: '就业区域统计',
clock: '打卡管理',
clockCheck: '打卡审核',
clockCount: '打卡统计',
clockRemind: '打卡提醒',
clockConfig: '配置打卡',
wageCount: '薪酬区间统计',
majorCount: '专业相关统计',
wageAvgCount: '薪酬平均统计',
scoreCount: '成绩统计',
scoreCheck: '资格审查',
scoreMake: '成绩生成',
analysis: '分析和诊断',
studentWarn: '问题学生预警',
article: '文章管理',
createArticle: '添加文章',
editArticle: '编辑文章',
Expand All @@ -15,8 +39,8 @@ export default {
Users: '用户管理',
User: '个人中心',
UserList: '用户列表',
MessageList: '所有留言',
Messages: '留言管理',
MessageList: '所有反馈',
Messages: '系统反馈',
FieldList: '字段列表'
},
navbar: {
Expand All @@ -29,5 +53,11 @@ export default {
logIn: '登录',
email: '邮箱',
password: '密码'
},
tagsView: {
refresh: '刷新',
close: '关闭',
closeOthers: '关闭其它',
closeAll: '关闭所有'
}
}
2 changes: 2 additions & 0 deletions resources/assets/js/store/getters.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const getters = {
sidebar: state => state.app.sidebar,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
device: state => state.app.device,
token: state => state.user.token,
userid: state => state.user.userid,
Expand Down
2 changes: 2 additions & 0 deletions resources/assets/js/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Vuex from 'vuex'
import app from './modules/app'
import permission from './modules/permission'
import user from './modules/user'
import tagsView from './modules/tagsView'
import category from './modules/category'
import getters from './getters'

Expand All @@ -13,6 +14,7 @@ const store = new Vuex.Store({
app,
permission,
user,
tagsView,
category
},
getters
Expand Down
3 changes: 2 additions & 1 deletion resources/assets/js/store/modules/permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ const permission = {
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
console.log(roles)
let accessedRouters
if (roles.includes('admin')) {
if (roles && roles.includes('admin')) {
accessedRouters = asyncRouterMap
} else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
Expand Down
162 changes: 162 additions & 0 deletions resources/assets/js/store/modules/tagsView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
const tagsView = {
state: {
visitedViews: [],
cachedViews: []
},
mutations: {
ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},

DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
},
DEL_CACHED_VIEW: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews.splice(index, 1)
break
}
}
},

DEL_OTHERS_VISITED_VIEWS: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews = state.visitedViews.slice(i, i + 1)
break
}
}
},
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews = state.cachedViews.slice(index, index + 1)
break
}
}
},

DEL_ALL_VISITED_VIEWS: state => {
state.visitedViews = []
},
DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
},

UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view)
break
}
}
}

},
actions: {
addView({ dispatch }, view) {
dispatch('addVisitedView', view)
dispatch('addCachedView', view)
},
addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view)
},
addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view)
},

delView({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delVisitedView', view)
dispatch('delCachedView', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delVisitedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_VISITED_VIEW', view)
resolve([...state.visitedViews])
})
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews])
})
},

delOthersViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delOthersVisitedViews', view)
dispatch('delOthersCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delOthersVisitedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
delOthersCachedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_CACHED_VIEWS', view)
resolve([...state.cachedViews])
})
},

delAllViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delAllVisitedViews', view)
dispatch('delAllCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delAllVisitedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_VISITED_VIEWS')
resolve([...state.visitedViews])
})
},
delAllCachedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_CACHED_VIEWS')
resolve([...state.cachedViews])
})
},

updateVisitedView({ commit }, view) {
commit('UPDATE_VISITED_VIEW', view)
}
}
}

export default tagsView
Loading

0 comments on commit fc0d7eb

Please sign in to comment.