什么是动态路由
动态路由,顾名思义,就是路由不在前端被写死,而是通过后端返回并渲染。这样做的好处主要有可以根据用户权限来展示不一样的页面层级,也可以随时配置路由信息,不用修改源码。
如何实现
既然这么好用,那么如何实现呢?
当然,这里需要一个接口来返回你所需要的路由信息,如果不会java可以用node来写,这里附上我的另一篇文章node.js写后台接口连接数据库。
至于前端实现,废话不多说直接上代码。
首先需要获取路由信息和处理数据以及存储等,所以需要在store下创建一个module,至于store的使用可以看我另一篇文章vuex的使用。这里我给他命名为permission.js
store/modules/permission.js
import { constantRoutes } from '@/router'//部分写死的路由,比如login
import { getRouters } from '@/api/login'//后台请求调用
import Layout from '@/layout/index'
const permission = {
state: {
routes: [],
addRoutes: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
},
actions: {
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {//请求路由数据
const accessedRoutes = filterAsyncRouter(res.data.router)//对请求回的路由进行处理
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
})
}
}
}
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap) {
return asyncRouterMap.filter(route => {
if (route.component) {
// Layout组件特殊处理
if (route.component === 'Layout') {
route.component = Layout
} else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children && route.children.length && route.children != []) {
route.children = filterAsyncRouter(route.children)
}else{
delete route.children
delete route.alwaysShow
}
return true
})
}
// 用作对组件解析,views是你存放页面的文件夹,根据需要自行调整
export const loadView = (view) => { // 路由懒加载
return (resolve) => require([`@/views/${view}`], resolve)
}
export default permission
然后根目录创建一个文件,命名随意(我这里叫permission.js),这个文件主要作用就是路由拦截
permission.js
import router from './router'
import store from './store'
// 消息提醒
import { Message } from 'element-ui'
// 进度条
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 最重要: 在路由加载跳转前调用的方法
router.beforeEach((to, from, next) => {// to是要跳转的路径信息
// 打开进度条
NProgress.start()
if (判断token是否获取到) {
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else {
if (条件) {
// 判断当前用户是否拉取过路由信息,如果没有获取过路由信息再进行以下步骤
store.dispatch('GenerateRoutes').then(accessRoutes => {
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
} else {
next()
}
}
} else {
// 没有token
if (判断是否是不需要登录的页面 eg:免登录的地址组成的数组.indexOf(to.path) !== -1) {
// 在免登录白名单,直接进入
next()
} else {
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
NProgress.done()
}
}
})
// 路由跳转后方法
router.afterEach(() => {
NProgress.done()
})
最后,在main.js中引入该文件使其生效
main.js
import '@/permission' // 引入@/permission.js,使其生效
剩下的就是左侧菜单的配置,这个根据你们自己使用的方法,从vuex中读取路由数据来渲染菜单。
写在最后
喜欢这篇文章的小伙伴们,留个赞再走吧