多页签中的visitedViews只存储部分字段

代码简化
移除path-to-regexp
master
toesbieya 6 years ago
parent 04f098842d
commit d125fba250
  1. 5
      vue/package-lock.json
  2. 1
      vue/package.json
  3. 2
      vue/src/config/index.js
  4. 13
      vue/src/layout/mixin/tagsViewPersistent.js
  5. 17
      vue/src/layout/store/tagsView.js
  6. 8
      vue/src/main.js
  7. 20
      vue/src/router/guardian/accessControl.js
  8. 8
      vue/src/router/guardian/avoidReuse.js
  9. 8
      vue/src/router/guardian/index.js
  10. 0
      vue/src/router/guardian/setTitle.js
  11. 27
      vue/src/router/index.js
  12. 2
      vue/src/router/util.js
  13. 4
      vue/src/store/index.js
  14. 2
      vue/src/store/module/app.js
  15. 24
      vue/src/store/module/socket.js
  16. 2
      vue/src/store/module/user.js
  17. 4
      vue/src/util/storage.js
  18. 2
      vue/src/view/app/login/LoginForm.vue
  19. 6
      vue/src/view/app/login/RegisterForm.vue
  20. 2
      vue/src/view/system/user/indexPage.vue

@ -10092,11 +10092,6 @@
"integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=",
"dev": true
},
"path-to-regexp": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.1.0.tgz",
"integrity": "sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw=="
},
"path-type": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",

@ -17,7 +17,6 @@
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"pako": "^1.0.11",
"path-to-regexp": "^6.1.0",
"socket.io-client": "^2.3.0",
"vue": "^2.6.11",
"vue-count-to": "^1.0.13",

@ -8,7 +8,7 @@ module.exports = {
//项目的部署路径,始终以'/'开头,以'/'结束
contextPath,
//页面标题、登注册页的标题
//页面标题、登注册页的标题
title: 'BiuBiuBiu~',
//全局axios的baseUrl、devServer的路由前缀

@ -10,9 +10,7 @@ import {getTagsView, setTagsView} from "@/util/storage"
export default {
computed: {
shouldPersistent() {
return tagsViewGetters.persistent
}
shouldPersistent: () => tagsViewGetters.persistent
},
watch: {
@ -36,15 +34,8 @@ export default {
}
},
methods: {
persistentTagsView(v) {
//只提取部分属性
setTagsView(v.map(({name, path, fullPath, meta}) => ({name, path, fullPath, meta})))
}
},
beforeCreate() {
this.persistentTagsView = debounce(this.persistentTagsView)
this.persistentTagsView = debounce(setTagsView)
},
mounted() {

@ -35,23 +35,30 @@ export const mutations = bindThis({
enabled(v) {
store.enabled = v
//多页签停用时清除所有页面缓存
!v && this.delAllViews()
},
addVisitedView(view) {
if (store.visitedViews.some(v => v.path === view.path)) return
addVisitedView({name, path, fullPath, meta = {}}) {
if (store.visitedViews.some(v => v.path === path)) {
return
}
store.visitedViews.push(view)
store.visitedViews.push({name, path, fullPath, meta: {...meta}})
},
addCachedView(view) {
const {noCache, iframe, usePathKey, useFullPathKey} = view.meta || {}
if (noCache || iframe || !view.name && !usePathKey && !useFullPathKey) return
if (noCache || iframe || !view.name && !usePathKey && !useFullPathKey) {
return
}
const key = getRouterViewCacheKey(view)
if (store.cachedViews.includes(key)) return
if (store.cachedViews.includes(key)) {
return
}
store.cachedViews.push(key)
},

@ -27,10 +27,4 @@ new Vue({
})
//页面刷新时socket重连
store.dispatch('socket/init', store.state.user).catch()
window.addEventListener('unhandledrejection', event => {
if (event.reason.stack.startsWith('Error: Redirected when going from')) {
event.preventDefault()
}
})
store.dispatch('socket/init').catch()

@ -1,18 +1,17 @@
import {pathToRegexp} from 'path-to-regexp'
import store from "@/store"
import {isEmpty} from "@/util"
import {auth, needAuth} from "@/util/auth"
import {isUserExist} from "@/util/storage"
const whiteList = ['/login', '/register', '/403', '/404', '/500'].map(url => pathToRegexp(url))
const noLoginList = ['/login', '/register', '/403', '/404', '/500']
const beforeEach = async (to, from, next) => {
//白名单内不需要进行权限控制
if (whiteList.some(reg => reg.test(to.path))) {
//放行不需要登录即可访问的路由
if (noLoginList.includes(to.path)) {
return next()
}
//未登录时返回登录页
if (!isUserExist()) {
if (isEmpty(store.state.user.id, store.state.user.token)) {
return next({path: '/login', query: {redirect: to.fullPath}})
}
@ -31,11 +30,12 @@ const beforeEach = async (to, from, next) => {
next('/403')
}
//获取进行权限验证的路由地址,使用了动态路由的会用到
//获取进行权限验证的路由地址
function getAuthorizedPath(route) {
const {params, path, matched} = route
const isDynamic = Object.values(params).some(v => path.includes(v))
return isDynamic ? matched[matched.length - 1].path : path
const {path, matched} = route, len = matched.length
//可能会有路由使用动态路径(诸如/:id),matched中的path是routeConfig中声明的原始路径
return len > 0 ? matched[len - 1].path : path
}
export default function (router) {

@ -5,7 +5,7 @@ const beforeEach = (to, from, next) => {
const a = to.meta.commonModule, b = from.meta.commonModule
const isComponentReuse = !isEmpty(a) && a === b
if (isComponentReuse) {
//这里vue-router会报redirect错误,已在main.js中忽略
//这里vue-router会报redirect错误,已在下方忽略
return next(`/redirect${to.fullPath}`)
}
next()
@ -14,3 +14,9 @@ const beforeEach = (to, from, next) => {
export default function (router) {
router.beforeEach(beforeEach)
}
window.addEventListener('unhandledrejection', event => {
if (event.reason.stack.startsWith('Error: Redirected when going from')) {
event.preventDefault()
}
})

@ -1,13 +1,13 @@
import nprogress from './nprogress'
import avoidReuse from './avoidReuse'
import setInfo from './setInfo'
import security from './security'
import setTitle from './setTitle'
import accessControl from './accessControl'
import iframe from './iframe'
export default function (router) {
nprogress(router)
avoidReuse(router)
setInfo(router)
security(router)
accessControl(router)
setTitle(router)
iframe(router)
}

@ -1,16 +1,17 @@
/*
* 路由配置
*
* 需要鉴权的路由!meta.noAuth
* 左侧菜单显示name && !meta.hidden && meta.title
* 左侧菜单排序能在左侧菜单中显示 && meta.sort升序排列
* 左侧菜单不折叠只有一个children的路由meta.alwaysShow
* 页头显示meta.pageHeader !== false && (meta.title || meta.dynamicTitle)
* tab栏显示meta.title || meta.dynamicTitle
* tab栏固定显示meta.title && meta.affix
* 页面不缓存!name && !meta.usePathKey && !meta.useFullPathKey || meta.noCache
* 打开iframemeta.iframe不会重复打开相同src的iframe
* */
/**
* 路由配置说明
*
* 不需要鉴权的路由meta.noAuth
* 左侧菜单显示name && !meta.hidden && meta.title
* 左侧菜单排序能在左侧菜单中显示 && meta.sort升序排列
* 左侧菜单不折叠只有一个children的路由meta.alwaysShow
* 页头显示meta.pageHeader !== false && (meta.title || meta.dynamicTitle)
* tab栏显示meta.title || meta.dynamicTitle
* tab栏固定显示meta.title && meta.affix
* 页面不缓存!name && !meta.usePathKey && !meta.useFullPathKey || meta.noCache
* 打开iframemeta.iframe不会重复打开相同src的iframe
*/
import Vue from 'vue'
import Router from 'vue-router'
import {route as routeConfig} from '@/config'

@ -128,7 +128,7 @@ export function generateRoutes(jsonTree) {
return jsonTree
}
//子路由继承父路由meta上的{noAuth,noCache},优先使用子路由的值
//子路由继承父路由meta上的{noAuth, noCache},优先使用子路由的值
export function metaExtend(routes, parentMeta) {
const keys = ['noAuth', 'noCache']
routes.forEach(route => {

@ -15,6 +15,4 @@ const modules = modulesFiles.keys().reduce((modules, modulePath) => {
return modules
}, {})
export default new Vuex.Store({
modules
})
export default new Vuex.Store({modules})

@ -1,7 +1,7 @@
import {createMutations} from "@/store/util"
const state = {
//登页背景动画
//登页背景动画
loginBackgroundAnimation: 'sparkRain',
}

@ -13,21 +13,19 @@ const state = {
const mutations = createMutations(state)
const actions = {
init(context, user) {
if (useMock || isEmpty(user, user.id, user.token)) return
init(context) {
const {id, token} = context.rootState.user
socket = initSocket(user)
if (useMock || isEmpty(id, token)) return
defaultEventBind(socket, context)
customEventBind(socket, context)
socket = initSocket({id, token})
bindDefaultEvent(socket, context)
bindCustomEvent(socket, context)
},
close() {
return new Promise(resolve => {
if (!socket) return resolve()
socket.close()
resolve()
})
socket && socket.close()
}
}
@ -35,7 +33,7 @@ function initSocket({id, token}) {
return new SocketIO(socketUrl, {query: {id, token}, transports: ['websocket']})
}
function defaultEventBind(socket, {state, commit, dispatch}) {
function bindDefaultEvent(socket, {state, commit, dispatch}) {
socket.on('connect', () => {
commit('online', true)
console.log('socket连接成功')
@ -72,10 +70,10 @@ function defaultEventBind(socket, {state, commit, dispatch}) {
})
}
function customEventBind(socket, {state, commit, dispatch, rootState}) {
function bindCustomEvent(socket, {state, commit, dispatch, rootState}) {
socket.on('logout', msg => {
if (rootState.user.prepareLogout) return
MessageBox.alert(msg || '你已被强制下线,请重新登', {
MessageBox.alert(msg || '你已被强制下线,请重新登', {
type: 'warning',
beforeClose: (action, instance, done) => {
dispatch('user/logout', null, {root: true}).finally(done)

@ -35,7 +35,7 @@ const actions = {
user.avatar = autoCompleteUrl(user.avatar)
commit('$all', user)
setUser(user)
return dispatch('socket/init', user, {root: true})
return dispatch('socket/init', null, {root: true})
})
},

@ -59,10 +59,6 @@ const sessionUserKey = 'SESS-USER'
const localPersonalSettingsKey = 'LOCAL-PERSONAL-SETTINGS'
const sessionTagsViewKey = 'SESS-TAGS-VIEW'
export function isUserExist() {
return exist(sessionUserKey)
}
export function getUser() {
let user = get(sessionUserKey)
if (isEmpty(user)) {

@ -104,7 +104,7 @@ export default {
},
success() {
elSuccess('登成功')
elSuccess('登成功')
const redirect = this.$route.query.redirect || '/'
//0.2s
window.setTimeout(() => this.$router.replace(redirect), 200)

@ -4,7 +4,7 @@
<span class="svg-container">
<v-icon icon="svg-user"/>
</span>
<el-input ref="username" v-model="form.username" :maxlength="20" placeholder="请输入登名称"/>
<el-input ref="username" v-model="form.username" :maxlength="20" placeholder="请输入登名称"/>
</el-form-item>
<el-form-item prop="nick">
@ -47,7 +47,7 @@
<div class="flex" style="margin-top: 20px">
<p/>
<el-button type="text" @click="login">已有账户登</el-button>
<el-button type="text" @click="login">已有账户登</el-button>
</div>
</el-form>
</template>
@ -86,7 +86,7 @@ export default {
},
rules: {
username: [
{required: true, message: '请输入登名称', trigger: 'change'},
{required: true, message: '请输入登名称', trigger: 'change'},
{validator: validateLoginName, trigger: 'change'}
],
nick: [

@ -50,7 +50,7 @@
@click.stop="() => previewAvatar(row.avatar)"
>
</el-table-column>
<el-table-column align="center" label="登名" prop="loginName" show-overflow-tooltip/>
<el-table-column align="center" label="登名" prop="loginName" show-overflow-tooltip/>
<el-table-column align="center" label="昵称" prop="nickName" show-overflow-tooltip/>
<el-table-column align="center" label="角 色" show-overflow-tooltip>
<template v-slot="{row}">

Loading…
Cancel
Save