Vue-element-admin动态加载路由学习
关于vue-element-admin中动态加载路由
主要的两个js文件为src/permission.js和store/models/permission.js
src/perminssion.js 比较关键的代码如下:
router.beforeEach(async(to, from, next) => { NProgress.start() document.title = getPageTitle(to.meta.title) const hasToken = getToken() if (hasToken) { if (to.path === '/login') { next({ path: '/' }) NProgress.done() } else { const hasRoles = store.getters.roles && store.getters.roles.length > 0 if (hasRoles) { next() } else { try { const { roles } = await store.dispatch('user/getInfo') const accessRoutes = await store.dispatch('permission/generateRoutes', roles) router.addRoutes(accessRoutes) next({ ...to, replace: true }) } catch (error) { await store.dispatch('user/resetToken') Message.error(error || 'Has Error') next(`/login?redirect=${to.path}`) NProgress.done() } } } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { next(`/login?redirect=${to.path}`) NProgress.done() } } })
可知在permission.js文件中 通过调用router.beforeEach()方法再每次请求时判断获取用户的详细信息和通过用户信息中的角色构造路由
const { roles } = await store.dispatch('user/getInfo')
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
router.addRoutes(accessRoutes)
vuex 对应的user/getInfo 行为的代码为
getInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo(state.token).then(response => { const { data } = response if (!data) { reject('Verification failed, please Login again.') } const { roles, name, avatar, introduction } = data // roles must be a non-empty array if (!roles || roles.length <= 0) { reject('getInfo: roles must be a non-null array!') } commit('SET_ROLES', roles) commit('SET_NAME', name) commit('SET_AVATAR', avatar) commit('SET_INTRODUCTION', introduction) resolve(data) }).catch(error => { reject(error) }) }) },
可知,用户在登录的情况下都会通过vuex请求一次都向后端发送了一次getInfo()请求获取用户最新的数据信息并提交role,name,avatar,introuction等信息存于vuex
当js执行到此处时
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
该语句对应的vuex permission/generateRoutes行为的代码则需要重点关注store/permission.js这个文件
store/modules/permission.js的内容如下
import { asyncRoutes, constantRoutes } from '@/router' function hasPermission(roles, route) { if (route.meta && route.meta.roles) { return roles.some(role => route.meta.roles.includes(role)) } else { return true } } export function filterAsyncRoutes(routes, roles) { const res = [] routes.forEach(route => { const tmp = { ...route } if (hasPermission(roles, tmp)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles) } res.push(tmp) } }) return res } const state = { routes: [], addRoutes: [] } const mutations = { SET_ROUTES: (state, routes) => { state.addRoutes = routes state.routes = constantRoutes.concat(routes) } } const actions = { generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes if (roles.includes('admin')) { accessedRoutes = asyncRoutes || [] } else { accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) } commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) } } export default { namespaced: true, state, mutations, actions }
前面提到src/permission.js 向vuex分发了permission/generateRoutes并将roles作为参数传递给vuex,通过方法名可知其功能就是完成创建路由的行为该方法会返回可访问路由accessedRoutes
而对应的行为代码为上面代码的generateRoutes方法,该行为通过判断传递过来的roles中是否包含admin这个角色,如果有则将动态路由asyncRoutes赋值给accessedRoutes,如果不包含则调用filterAsyncRoutes()方法将动态路由asyncRoutes和roles传递到该方法中,filterAsyncRoutes()通过判断route.meta.roles是否存在对应的角色,将具有对应角色的路由添加到res中并返回给accessedRoutes
再commit('SET_ROUTES', accessedRoutes) 提交
最后当代码执行到src/permission.js的
router.addRoutes(accessRoutes)
调用router.addRoutes()方法添加可访问的路由列表
总结
vue-element-admin默认的动态路由加载是通过判断router中的meta.roles是否包含对应的role,并进行加载指定的路由,而这些路由都写在了router/index.js文件中,那么后端则只需要进行角色的分配然后由前端的store/perminss.js的filterAsyncRoutes
动态构建路由并加载说白了后端就是相当于不用分配每个角色对应的权限和菜单 因为这部分的都有store/perminss.js中方法进行动态构建了
本文作者:初夏†失忆
本文链接:https://www.cnblogs.com/Esummer/p/13920399.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步