next('xxx') 再一次走router.beforeEach路由守卫回调, next()表示加载路由
- 登录路由判断 判断token存在, 使用store插件,可以限制token存在的时间(在生成一个带有时间的token如_expireTimeToken = 1234123132) token 不存在,重定向/login,通过allowList判断,加载login路由
const allowList = ['login']
router.beforeEach((to: any, from, next) => {
const token = storage.get('ACCESS_TOKEN')
if (token) {
...
next()
} else if (allowList.includes(to.name)) {
next()
} else {
next('/login')
}
})
- 动态路由
vuex state routes属性,判断路由存在, 页面一刷新就不在了。防止正常页面点击加载路由,进行动态路由添加。
const allowList = ['login']
router.beforeEach((to: any, from, next) => {
const token = storage.get('ACCESS_TOKEN')
if (token) {
if (store.state.routes.length == 0) {
store.dispatch('GenerateRoutes')
// 动态添加路由后,再次重定向默认路径或网址路径
// next('xxx') 再一次走router.beforeEach路由守卫回调, next()表示加载路由
next(to.path == '/' ? '/aggregator' : to.path)
} else {
// 判断加载路由成功后,breadInfoArr面包屑变化,navMenuInfoArr 左侧导航栏变化
const r_path_arr = to.path.split('/')
r_path_arr.shift()
breadInfoArr.value = r_path_arr
navMenuInfoArr.value = to.meta.level ? r_path_arr.slice(0, -(to.meta.level - 1)) : r_path_arr
// 带参数的url页面,点击左上角刷新参数缺失问题
if (to.redirectedFrom && to.redirectedFrom.path == to.path && to.redirectedFrom.query != to.query) {
to.query = to.redirectedFrom.query
to.fullPath = to.redirectedFrom.fullPath
}
next()
}
} else if (allowList.includes(to.name)) {
next()
} else if (from.name == 'login') {
// 登陆页面,没有token,阻止重定向其他页面
next(false)
} else {
next('/login')
}
})
vuex
createStore({
state: {
routes: []
},
mutations: {
SET_ROUTERS: (state, routes) => {
state.routes = routes
}
},
actions: {
Logout ({ commit }) {
commit('SET_ROUTERS', [])
},
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
// 过滤路由
const accessedRouters = filterRouter(['home', 'dashboard', 'form'])
commit('SET_ROUTERS', accessedRouters)
resolve(accessedRouters)
})
}
},
modules: {
}
})
const filterRouter = (permission: string[]) => {
permission_arr = permission
// 过滤动态路由列表
const routers = filterAsyncRouter(router_config)
// 往路由router中添加 过滤后的路由
addNavRouters(routers)
// 导航菜单数据 赋值
filterRoutes.value = routers
return routers
}
addNavRouters = (rs: Array<RouteRecordRaw>, parentName = 'index') => {
// 登出后,会删除index组件,需要添加回来
if (!router.hasRoute('index')) {
router.addRoute(common_router[0])
}
rs.forEach((r) => {
router.addRoute(parentName, r)
})
return router
}
// 登出
const logout = () => {
store.dispatch('Logout')
router.push('/login')
router.removeRoute('index')
}
-
按钮权限控制
使用自定义指令实现,官方文档链接 app.directive 注册全局指令。mounted 和 updated 生命周期,相同的行为,采用简化方式书写。响应式变量使用arg. el 和 binding解释看官方文档 authDirective函数书写权限控制逻辑
const authDirective = (el, binding) => {
// mounted 和 updated 生命周期,相同的行为
// arg v-auth:[responed] responed响应式的变量
el.style.display = binding.arg != "delete" ? "none" : "block"
}
app.directive("auth", authDirective)
指令使用, newshow 是响应式变量
<a-button v-auth:[newshow] class="add-btn" type="primary" @click="edit(0)">
<template #icon>
<plus-outlined />
</template>
新增
</a-button>
const newshow = ref('delete')