先说说这里为什么要使用动态路由?
因为前面的菜单管理功能模块中,可以创建或修改不同权限,当前登录账号可以绑定不同的权限,不同权限能访问的功能页面不同,所以使用动态路由来控制。
而登录成功后,服务器返回的数据中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