先说说这里为什么要使用动态路由?
因为前面的菜单管理功能模块中,可以创建或修改不同权限,当前登录账号可以绑定不同的权限,不同权限能访问的功能页面不同,所以使用动态路由来控制。
而登录成功后,服务器返回的数据中component的属性值是个路径(见图),但实际上我们需要的是一个vue文件,需要根据现在得到的component的路径找到vue文件
这是之前写死的路由信息,component部分是直接通过开头的import找到组件,所以需要把当前获取到的返回数据稍作处理
这里借助vite的glob,从文件系统导入模块。然后将更新后的路由列表挂载到state上
dynamicMenu(state, payload) {
console.log(payload);
// 通过glob导入模块
// 获得的是每个views下面的路径
// 导入view文件下的文件下的文件中的所有后缀为vue的
const moudules = import.meta.glob('../views/**/**/*.vue')
console.log('moudules:', moudules);
function routerSet(router) {
router.forEach(route => {
// 有componnet就代表如果当前路由下没有孩子 就拼接路由路径
if (!route.children) {
const url = `../views${route.meta.path}/index.vue`
// 拿到获取的vue组件 设置导路由配置的component上
route.component = moudules[url]
} else {
// 有子菜单就要递归
routerSet(route.children)
}
});
}
// 拿到完整的路由数据进行递归
routerSet(payload)
//将更新后的路由列表挂载state上
state.routerList = payload
},
登录界面中登录完成后,根据当前用户权限列表,添加动态路由,控制其访问权限
// 登录页面
login(loginForm).then(({data})=>{
if(data.code === 10000){
console.log('登录成功');
ElMessage.success('登录成功')
// 页面跳转 token信息缓存
console.log('login',data);
localStorage.setItem('pz_token',data.data.token)
localStorage.setItem('pz_userInfo',JSON.stringify(data.data.userInfo))
menuPermissions().then(({data})=>{
// 调用store里面的动态菜单函数将component的路径变成完整vue文件路径
store.commit('dynamicMenu',data.data)
//更新之后动态的路由信息 通过computed获取到state里的数据
console.log('routerList',routerList);
// toRaw把响应式的数据变成普通的对象数据 只需要保存main 原始第一个路由路径 后面的都根据下面动态添加
toRaw(routerList.value).forEach(item => {
// 添加动态路由
router.addRoute('main',item)
});
// 登录成功跳转到首页
router.push('/')
})
}
})
that’s all