很多时候使用vue开发后台管理系统需要动态菜单权限,这样的话前端不能写一些静态的路由地址,只能写一些如login、404等路由,其他路由基本都是后端的同学通过接口返回给前端的,那要如何配置呢?
话不多说直接上代码
1、整体项目结构
2、本地路由配置
在项目src/router目录中新建一个router.js文件,写入本地的路由配置
import Home from '@/views/home'
export default [{
path: '/login',
name: 'login',
title: false,
meta: {
title: "登录"
},
component: () => import('@/views/login/index.vue')
},
{
path: '/404',
name: '404',
title: false,
meta: {
title: "error"
},
component: () => import('@/views/error/404.vue')
}
]
3、动态路由方法配置
在src秘录中新建utils文件夹,在utils中创建两个js文件,menufilter.js(处理组件路由逻辑)和lazyLoading.js(动态处理与返回路由实例组件)
1、menufilter.js
import {
lazy
} from './lazyLoading' //引入lazyLoading.js文件,返回的是组件实例
import Home from '../views/home' //引入主路由组件
export function Menufilter(data) {
//data为login.vue组件中,登陆成功后,获取后台给的菜单数据
let routers = [] //定义一个空数组
let chiObj = {} //定义一个空对象
data.forEach((item, index) => {
let childrenArr = [];
item.children.forEach((items, indexs) => {
let COMPONENT = lazy(items.path) //关键点,items.path是组件的路径,调用lazy函数处理
//组织子路由的各个属性
chiObj = {
path: items.title,
component: COMPONENT,
name: items.name,
key: items.key,
parentId: items.parentId,
meta: {
title: items.name
},
}
childrenArr.push(chiObj)
})
//组织父路由的各个属性
let objRou = {
path: '/',
component: Home,
title: item.title,
name: item.name,
key: item.key,
children: childrenArr,
meta: {
title: item.name
},
}
if (!item.title) {
objRou.redirect = item.children[0].title
}
routers.push(objRou)
})
return routers
}
2、lazyLoading.js
function lazy(name) {
return () => import(`@/views${name}.vue`)
}
export {
lazy
}
4、登录获取路由配置
login.vue组件
<template>
xxx
</template>
<script>
import { Menufilter } from "../../utils/menufilter";
import { resetRouter} from "@/router/index.js";
resetRouter
...
methods:{
//请求获取菜单方法
XXX().then((data)=>{
//重置路由实例
resetRouter()
//把后端同学给的路由菜单存一份至localStorage中
localStorage.setItem("routes", JSON.stringify(data));
//调用Menufilter方法处理菜单
this.$router.options.routes = this.$router.options.routes.concat(
Menufilter(data)
);
//把处理好的菜单addRoutes至Routes实例中
this.$router.addRoutes(Menufilter(data));
})
//
}
</script>
5、路由主逻辑
在项目src/router目录中新建一个index.js文件
import Router from 'vue-router'
import Cookies from 'js-cookie'
import routes from './routers'
import {
Menufilter
} from "../utils/menufilter";
Vue.use(Router)
//处理多次点击已选路由报错问题
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
//获取登陆时存入localStorage中的路由菜单数据
//刷新页面时,获取登陆时存入localStorage中的菜单数据,重新加载处理路由菜单
let routesData = JSON.parse(localStorage.getItem("routes"));
//实例化Router
const createRouter = () => new Router({
mode: 'history',
routes: routes
})
const router = createRouter()
//重新实例化router,该方法是为了解决,切换用户时,router默认不会重新实例化,这样就会导致,之前addRoutes至router的路由组件依然存在,如果需要解决这个问题,只需要在login.vue组件中调用此方法
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher
router.options.routes = routes
}
//routesData不等于空时,利用Menufilter函数处理路由并返回add至router路由实例中
if (routesData != null) {
router.options.routes = router.options.routes.concat(Menufilter(routesData));
router.addRoutes(Menufilter(routesData));
}
到此,动态路由已经配置完成!!!