使用vue开发一些功能时,需要动态的判断是否有权限进入该路由,特别是一些后台系统,如果单一的只有几个角色的权限配置还好,如果是每个权限都需要配置,这个时候就需要使用到vue的动态路由了.
一般的动态路由,有固定的权限的,可以在前端存储一份权限路由,可以移步 vue-element-admin,比较详细.
所有路由(不包括404等通用路由)做动态路由,使用vue-element-admin的那种做法是不可取的,因为每个权限都需要可以控制.
-
我们需要后端的配合,如果后端给的数据格式不合适,你需要做大量的操作来洗数据,数据格式可以按照这种:
[ { "id": 0, "children": [ { "id": 1, "children": [] } ] } ]
- 获取到数据之后我们需要在路由拦截器中判断是否登录,如果登录获取权限进行动态路由添加.
router.beforeEach(async(to, from, next) => {
//判断token是否存在的函数
const hasToken = getToken()
//token存在,已经登录
if (hasToken) {
//判断路由是否已经保存了
if(!store.getters.addRouter.length){
//请求路由的api
getLoginUserPermission()
.then((res)=>{
//拷贝路由数据
const data=JSON.stringify(res.data.data)
//路由筛选函数
const addRoute=filterAsyncRouter(res.data.data)
//如果需要二次筛选
addRoute.forEach((Item,index)=>{
Item.children.forEach((Items,indexs)=>{
delete addRoute[index].children[indexs].children
})
})
// 存储路由到vuex中
store.dispatch('user/AddRouter', res.data.data)
// 动态路由添加
router.addRoutes(addRoute)
//添加完动态路由再将404跳转添加
router.addRoutes([{ path: '*', redirect: '/404', hidden: true }])
next({ ...to, replace: true })
})
}
next()
})
- filterAsyncRouter 路由筛选函数.
const _import = require('./_import_' + process.env.NODE_ENV)//获取组件的方法 //Layout 是架构组件,不在后台返回,在文件里单独引入
import Layout from '@/layout/layout.vue'
function filterAsyncRouter(asyncRouterMap) { //遍历后台传来的路由字符串,转换为组件对象
const accessedRouters = asyncRouterMap.filter(route => {
if (route.component) {
if (route.component === 'Layout') {//Layout组件特殊处理
route.component = Layout
} else {
route.component = _import(route.component)
}
}
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
return accessedRouters
}
export default filterAsyncRouter
- 区分生产环境与开发环境.
- 新建_import_development.js(开发环境)
module.exports = (file) => { // 路由懒加载
return () => import(`@/view/${viewPath}`)
}
- 新建_import_production.js(生产环境)
// 生产环境使用懒加载打包后会找不到js文件,有知道的朋友可以下方留言告诉我一下.
module.exports = (file) => {
return (resolve) => require(['@/views/' + file + '.vue'], resolve)
}
- 动态路由常见问题.
- (404问题):404路由不能直接加载到路由问题,动态路由添加时无法匹配到路由,所以都会跳转到404路由,所以需要在添加完动态路由后再添加404路由.
- 刷新后页面空白问题,需要在路由拦截器中添加
router.addRoutes(newRouter)
后需要next({ ...to, replace: true })
,具体原因还没找到,后续找到会在此记录.
Comments | NOTHING