一、背景
现在很多公司的vue项目都是一套模板加平台配置系统。角色权限、菜单名称、菜单图标都可以在平台配置系统上傻瓜式配置。笔者这篇文章主要讲解其中的动态路由,如果你是一位前端工程师,我想你会渴望知道其中的代码是如何实现的,如果你是后端工程师,希望我下面的代码不是那么晦涩难懂。另外我很欣赏你爱学习的精神。话不多说下面就是干货了~
二、代码实现
为了更方便的学习,笔者模拟了后端的接口数据,你可以复制粘贴直接使用~
export const dynamicRouters = [{path: '/home', //注意不要重复,唯一!!name: 'home', //注意不要重复,唯一!!mate: {title: '首页', //这个是菜单项名字icon: 'el-icon-s-home', //图标class 可以先不管},component: "/home/home", 这个是组件路径,正常来说是'@component/home/home'}
]
好了拿到数据之后,我们需要在用户登陆成功后动态加入,这里为了方便,不管他是什么角色有什么权限,我都返回上面的路由,如果在业务场景中,你可以让后台根据不同角色返回不同的路由,从而实现权限控制。下面再src下新建一个permission.js文件放入如下代码
import router from './router' //默认路由文件,可以放不用权限配置的页面
import store from './store/store' // vuex 一般路由数据都存在这里面,为了全局的数据绑定。
import { dynamicRouters } from "./components/mock.js" //这里就是后台返回的数据你懂的~router.beforeEach((to, from, next) => {if (sessionStorage.getItem('token')) { //判断用户是否已经登陆if (to.path === '/' && sessionStorage.getItem('token')) {next({ path: '/home' })} else {if (store.getters.menuRouter.length === 0) { //这里判断下vuex中是否有了动态路由数据store.dispatch('SET_MENU_ROUTER', dynamicRouters).then(() => { //这里对后台数据做处理router.addRoutes(store.getters.menuRouter) //关键看这里 取出后台数据,把数据从这加入next({ path: to.path === '/home' ? '/home' : to.path })})} else {next();}}} else {next();}
})
注意还没完,上面我们执行store.dispath('SET_MENU_ROUTER',dynamicRouters)方法对数据进行了处理,你也需要,代码如下
//这里是vuex的内容,我默认你是会的~~
const importRouter = (url) => {return () => import('@/components' + url) //这里把真实路径补正确
}function filterAsyncRouter(asyncRouterMap) { //递归处理路由懒加载const accessedRouters = asyncRouterMap.filter(route => {route.component = importRouter(route.component)if (route.children && route.children.length) {route.children = filterAsyncRouter(route.children)}return true})return accessedRouters
}
const state = {menuRouter: [], // 存储路由
}
const getters = {menuRouter: (state) => {return state.menuRouter //返回给addRouter使用},
}
const mutations = {setMenuRouter(state, menuRouter) {state.menuRouter = menuRouter // 设置存储},
}
const actions = {SET_MENU_ROUTER({ commit }, menuRouter) {return new Promise(resolve => {const accessedRouters = filterAsyncRouter(menuRouter) //调用// console.log(accessedRouters);commit('setMenuRouter', accessedRouters) //调用mutations中的方法,你懂的~resolve() //回调实现})},
}
搞定!