动态路由的作用
- 权限管理(主要原因)
- 路由多的时候,手动挂载繁琐
第一步先封装一个处理获取到的路由数据的方法(根据后端数据格式,具体情况具体分析)本文章的数据格式为
[{
nav: "",
comp_path: '',
navList: [{
title: "",
name: '',
path: '',
component: ''
}]
}]
-- 在src文件夹中创建一个untils文件夹,并创建一个js文件,在此文件中封装处理数据以及动态挂载路由的方法
//引入获取侧边栏路由数据的接口
import { aside } from '../api/admin';
//引入路由
import router from '@/router/index';
//动态挂在路由的方法
async function getChildrenpath() {
//此数组用来保存处理好的路由数据
const routerList = [];
//发送请求获取路由列表
let list_ = await aside();
//将路由列表存到vuex中
// console.log(list_)
//生成子路由数组
list_.forEach(item => {
setChild(item, routerList, '')
})
//父路由
let rou = {
name: 'home',
path: '/',
component: () => import("@/views/Index.vue"),
children: routerList
}
// console.log(rou)
//挂载所有路由
router.addRoute(rou)
}
//封装生成子级路由数组的方法
function setChild(item, routerList, rootPath) {
// item 循环的元素
//routerList 子路由数组列表
//rootPath 子路由组件 所在的父文件夹路径
if (item.navList != null && item.navList != [] && item.navList.length > 0) {
//说明有子级
item.navList.forEach(node => {
//继续判断子级有没有子级
setChild(node, routerList, item.comp_path)
})
} else {
//没有下一层 说明这是一个路由
let rou = {
name: item.name,
path: item.path,
component: () => import('../components' + rootPath + item.component)
}
routerList.push(rou)
}
}
//导出动态挂载路由的方法
export default {
getChildrenpath
}
在合适的时机调用方法动态挂载路由,当首次访问路由之前挂载最合适,所以本文章采取在全局前置路由守卫中调用函数,
import un from '@/untils/routerUntils'
let registerRouteFresh = true;//路由数据是否还没有动态加载过
router.beforeEach(async (to, from, next) => {
let isLogin=true;//模拟数据
if(to.path=='/login'){
isLogin=false;
}
if (isLogin) {
if (registerRouteFresh) {//还没有动态加载过
//动态注册路由 <----------------------------------------
await un.getChildrenpath();
registerRouteFresh = false;//已动态加载过
// ...to确保addRoutes操作完成,能够找到出口路由
next({ ...to, replace: true });
} else {
//已经登录了,不能再打开登录页
to.path === "/login" next("/") : next();
}
}
else {
//未登录,转向登录页面
to.path === "/login" next() : next("/login");
}
}
);