一、背景
现在很多公司的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() //回调实现
})
},
}
搞定!