本文续接上一篇博客vue权限控制——菜单及界面控制(含模拟数据)
使用同样一组模拟数据,但进行了部分修改,下载地址:提取码:Shin
提示:没有根据上一篇blog进行操作的建议直接下载此处文件,
所有在原文件基础上修改的代码都会伴随注释。
目录
数据初始化
此处提供的数据不包含依赖,需要自行通过控制台安装依赖
npm install
接下来是取消vue纠错 ,在文件夹下新增vue.config.js文件,写入以下代码
module.exports = {
lintOnSave: false
}
上一篇blog因为用不到,所以没有配置数据的路径信息,
现在在mock文件夹下index.js文件内修改路径
把所有authName为普通用户1的path改为'/menu/one'
把所有authName为普通用户2的path改为'/menu/two'
把所有authName为管理员1的path改为'/menu/three'
修改路由配置
通过上一篇blog,已经解决了用户角色权限的界面展示和菜单展示问题,
但是通过本blog修改数据后进行尝试,
发现可以在登录normal账户后通过地址栏访问管理员权限的路由页面
当然现实中后端会处理这个问题,但这里只是讨论一下使用方法
这是因为所有子路由都完成了注册,如果我们动态的注册路由,就不会发送这样的情况了
所以这里要再router文件夹下修改index.js文件里的路由配置
// const one ={
// path: '/menu/one',
// component: () => import('@/views/Page1.vue')
// }
//完成后启用
const two ={
path: '/menu/two',
component: () => import('@/views/Page1.vue')
}
const three = {
path: '/menu/three',
component: () => import('@/views/Page1.vue')
}
const routes = [{
path: '/',
name: 'Home',
component: Home,
redirect: '/menu/one',
children: [//此处留下一个均有权限的组件用于测试,完成后将此子路由删除
{
path: '/menu/one',
component: () => import('@/views/Page1.vue')
}
]
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '*',
name: 'NotFound',
component: NotFound
}
]
const routesMap={
// '/menu/one':one, 测试完成后启用
'/menu/two':two,
'/menu/three':three
}
那么现在 虽然管理员权限还能在菜单栏里看到另外两个菜单,但是已经无法跳转了
编写动态路由方法
接下来我们在本文件内写入动态添加路由方法
首先引入store,因为要用到vuex里的数据
import store from '../store/index.js'
随后编写并暴露动态路由方法
export function inputDynamicRoutes(){
//获得所有路由的数组
const currentRoute = router.options.routes
//获得权限账户的路由
const rights = store.state.user
//判定是否有账户登入信息
if(rights){
//遍历出权限路由的路径
rights.forEach(item=>{
item.children.forEach(child=>{
//判定是否存在权限路由路径
if(child.path){
//设置个临时变量接收权限路由路径对应的路由配置
let tempRoute = routesMap[child.path]
//把路由配置注册到父路由下
currentRoute[0].children.push(tempRoute)
currentRoute[0].children.forEach(v=>{
//vue3新的动态路由配置方法,参数是(parent,routeconfig)
router.addRoute('Home',v)
})
}
})
})
}
}
使用方法
方法编写好后需要在获取菜单数据之后使用
但是首先需要把router文件夹里index.js文件内,
home路由下刚刚留着测试用的children子路由内容清空
并且把const one那一行 和 routesMap对象里注释的内容解封
我们在Login.vue里引入方法
import{ inputDynamicRoutes } from'../router/index.js'
然后在获取数据的方法内使用
submitForm() {
this.$refs.form.validate(valid => {
if (valid) {
this.isLogin = true
this.$api.login({
username: this.userData.username,
password: this.userData.password
}).then(res => {
this.isLogin = false
if (!res.data) {
this.$message({
message: '用户名或密码错误!',
type: 'error'
})
return false
}
window.sessionStorage.setItem('rightslist',
JSON.stringify(res.data.rights))
window.sessionStorage.setItem('token', JSON.stringify(res.data.token))
this.setUser(res.data.rights)
//运行方法
inputDynamicRoutes()
this.$router.push('/')
})
}
return false
})
}
适用刷新
尝试之下我们发现,一旦刷新,动态路由页面又无法显示了,
因为刷新后,挂载在登录页的获取数据方法并没有被使用,所以动态路由没有加载
所以我们可以在App.vue里引入并使用该方法
import {inputDynamicRoute } from "@/router/index.js"
export default {
name: 'app',
//如果挂载在created和mounted里会报错,因为还没有获取数据,动态方法里使用到的vuex数据不存在
//虽然不影响使用,但是看着心烦,所以换成updated 毕竟路由一跳转就会触发
updated() {
inputDynamicRoute()
}
}
完成了