- 了解什么是RBAC权限设计思想
- 1.背景:
- 2.三个关键点:
- 3. 如何给用户添加功能:
- 4. 系统中的权限点可以随意添加吗?
- 5. 小结:
- 真正的步骤来了 , 看下面
- 一: 给员工分配角色
- 2. 弹层的基本交互
- 3. 获取角色列表并用el-checkedbox显示
- 小结: el-checkbox-group v-model=”数组”
- 4. 员工获取数据并回填
- 5. 保存
- 二: 给角色分配权限
- 1. 封装弹层组件
- 2. 弹层的基本交互
- 3. 获取权限点数据并显示
- 4. 设置 el-tree 的属性
- 5. 数据回填到el-tree中 (注意tree的回填和获取id)
- 6. 保存设置
- el-tree的小结:
- 三: 权限应用 - 做实际的权限控制 (左侧菜单的权限控制)
- 如何修改权限数据?
- 1. 动态生成左侧菜单 — addRoutes 方法
- addRoutes基本使用 *
- 1. 在router/index.js中的路由配置中删除动态路由的部分
- 核心代码: router.addRoutes(asyncRoutes)
- 实现效果: 这个时候左侧菜单是没有的,只能通过地址来访问到其他的页面
- 2. 动态生成左侧菜单- 改写菜单保存位置 *
- 落地代码: 将菜单数据保存在vuex中
- 四: 权限应用 - 使用权限数据做过滤处理
- 落地代码:
- 五: 权限应用 - 按钮级的权限控制
- 1. 自定义指令:
- 权限控制流程重点梳理总结——大总结
- 刷新页面时的bug修复
- 退出时重置路由:
- 数据回填问题 : created只执行一次
了解什么是RBAC权限设计思想
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625501490503-24ae21e9-f9bd-4d0b-97ea-793f903bb89b.png#clientId=ub8aed2bc-b045-4&from=paste&height=304&id=u9c067e1b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=304&originWidth=660&originalType=binary&ratio=1&size=63349&status=done&style=none&taskId=u2fe1596b-e294-4eb1-8986-f89830d74b9&width=660)
1.背景:
为了达成不同的帐号登陆系统后能看到不同的页面,能执行不同的功能的目标,我们有很多种解决方
案,RBAC(Role-Based Access control)权限模型 ,也就是基于角色的权限分配解决方案。
2.三个关键点:
用户: 就是使用系统的人(员工)
权限点:这个系统中有多少个功能(例始:有3个页面,每个页面上的有不同的操作)
角色:不同的权限点的集合
图示说明:
3. 如何给用户添加功能:
给用户分配角色,给角色分配权限点 (看上面那张图)
4. 系统中的权限点可以随意添加吗?
不能。必须是程序员已经开发出来的功能!!
5. 小结:
1. RBAC解决什么问题: 不同的人,有不同功能~
2. role-based access control
3. 三个主体: 用户 , 角色 , 权限点
真正的步骤来了 , 看下面
核心思想: 给员工分配角色,给角色分配权限,这样员工就有权限了
一: 给员工分配角色
1. 封装弹层组件
中间的步骤我就省了, 大概思路罗列到这里
目标: 在员工管理页面中,点击分配角色时,以弹层的方式打开/关闭组件
步骤: 封装组件,注册并且使用组件
子组件
背景:
目前系统中已经有一些角色,我们下面要将这些角色分配给不同的员工,让他们进入系<br /> 统后,做不同的事情。用户和角色是**1对多**的关系:一个用户可以拥有多个角色,这样他就会<br /> 具体这多个角色的权限了。比如公司的董事长可以拥有财务主管和保安队长的角色: 董事长<br /> 可以看财务报表,也可以查看监控。
2. 弹层的基本交互
目标: 完成显示关闭弹层的效果
效果: 点击分配角色,记录id , 显示弹层 , 然后是关闭弹层
3. 获取角色列表并用el-checkedbox显示
目标: 发请求获取本系统中所有的角色列表并显示在el-checkbox-group中
思路:
1. 准备静态的模板,学习el-checkbox-group 多选框
2. 准备api接口
3. 发请求,获取后端数据,再渲染
多选框: 对于用来表示多选的el-checkbox-group来说:
v-model的值是数组(表示多选)
它的子元素el-checkbox的label属性决定了选中这一项之后值
在模板中渲染:
小结: el-checkbox-group v-model=”数组”
4. 员工获取数据并回填
目标:
如果当前用户已经配置过一些角色数据,应该先把已经配置过的角色数据回显出来:
有些checkbox是选中的!
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625495268599-52ec5ac8-1d2a-49e3-896b-f7387f986683.png#clientId=ub8aed2bc-b045-4&from=paste&height=184&id=ue6ddbeb5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=184&originWidth=505&originalType=binary&ratio=1&size=21748&status=done&style=none&taskId=uceacd635-1804-4bb5-97f3-f5a9948c50b&width=505)
思路:
父组件中传入用户id (涉及到父传子,把需要的参数传过来)
在打开弹层后,根据用户id去获取当前的角色信息,再回显 (主要是根据接口中要求的 参数用id)
如何实现数据回填:
直接给data中你定义的那个数据项赋值
5. 保存
目标: 调用接口,将用户修改后的角色保存下来
思路:
封装接口 -> 调用接口
保存成功,要通知父组件关闭弹层
二: 给角色分配权限
为什么要给角色分配权限?
用户是什么角色(职位),他就具备某些功能<br /> 前面的代码中已经给用户加了角色了,那员工到底能做什么事,还是由角色中携带的具体的功能<br /> 来定的。<br /> ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625495868269-445226d8-0e3e-4203-bff0-a5c014d4f3e8.png#clientId=ub8aed2bc-b045-4&from=paste&height=377&id=u74b96625&margin=%5Bobject%20Object%5D&name=image.png&originHeight=377&originWidth=583&originalType=binary&ratio=1&size=69815&status=done&style=none&taskId=u152eea0c-146f-40ea-bf7d-4462f077ac6&width=583)<br /> ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625496113790-05052459-4a62-4ce7-bd69-d5fd7d49bc26.png#clientId=ub8aed2bc-b045-4&from=paste&height=383&id=u041b1d6c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=383&originWidth=519&originalType=binary&ratio=1&size=32291&status=done&style=none&taskId=u1ba2caf8-2913-4ee0-9dc4-ed2d05975e1&width=519)
这几个权限别乱加, 主要还是根据左侧菜单里面的内容来的,
1. 封装弹层组件
目标: 在角色管理页面中,点击分配权限时,以弹层的方式打开/关闭组件
步骤: 封装组件,注册并且使用组件
2. 弹层的基本交互
目标: 完成显示关闭弹层的效果
3. 获取权限点数据并显示
思路:
1. 准备权限点接口
2..弹框展示之后:
a . 调用api发请求获取数据;
b. 对数据进行格式转换(数组转树)
c. 模板绑定(把数据显示到el-tree上)
4. 设置 el-tree 的属性
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625496442329-4bf8fd6b-8f24-458a-8b37-376345d96a42.png#clientId=ub8aed2bc-b045-4&from=paste&height=252&id=u882ddb79&margin=%5Bobject%20Object%5D&name=image.png&originHeight=252&originWidth=447&originalType=binary&ratio=1&size=32813&status=done&style=none&taskId=u6c7f5ff7-dc99-480e-9de3-71cde086044&width=447)
目标: 对el-tree进一步设置:
1. 显示选择框
2. 默认全部展开
3. 关闭父子关联
配置属性:
1. show-checkbox 显示选择框
2. default-expand-all 默认展开
3. check-strictly 设置true,可以关闭父子关联
小结:
业务:一级:表示能否访问某个页面; 二级:表示能点击某个按钮
5. 数据回填到el-tree中 (注意tree的回填和获取id)
目标: 当前用户可能有一些已有的权限,需要我们回显出来
思路:
1. 准备api: 获取当前的角色已有的权限点
2. 组装 当前 参数 ,调用 api获取数据; (里面也涉及到了父传子,id)
3. 把数据回填显示到tree中
注意新知识点:
如何实现tree里面的数据回填? setCheckedKeys + node-key 处于选中状态
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625496940917-2c5f4fe7-4c79-444c-8e84-85d9045c50a8.png#clientId=ub8aed2bc-b045-4&from=paste&height=217&id=u1b16924c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=217&originWidth=254&originalType=binary&ratio=1&size=8428&status=done&style=none&taskId=uc6155a0d-6df4-44c5-a9e4-600ce7b681a&width=254) ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625496953700-311ede68-e133-4cf9-8e47-6bec055e8461.png#clientId=ub8aed2bc-b045-4&from=paste&height=68&id=u3e91e0f3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=68&originWidth=397&originalType=binary&ratio=1&size=3138&status=done&style=none&taskId=uecc52e6d-b878-4fa8-b026-8d383db9976&width=397)
6. 保存设置
目标: 完成权限分配的功能
思路: 准备api,点击保存的时候调用
这里的参数有两个:
1. 当前的角色id是什么? 在点击分配权限时,可以从表格中获取, 父传子
2 . 对应的权限列表id的是什么?通过el-tree组件的 getCheckedKeys来获取用户选中
的id列表
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625497302604-240b7285-9f30-423a-8817-75f8b01dcb09.png#clientId=ub8aed2bc-b045-4&from=paste&height=79&id=ucad8c830&margin=%5Bobject%20Object%5D&name=image.png&originHeight=79&originWidth=463&originalType=binary&ratio=1&size=9858&status=done&style=none&taskId=ue43fff45-eaf9-4076-86fb-8a1c60b19ed&width=463)
el-tree的小结:
获取当前选中的节点的keys : getCheckedKeys (获取当前用户选中的id列表)
设置:setCheckedKeys (比如上面的回填)
三: 权限应用 - 做实际的权限控制 (左侧菜单的权限控制)
说明:
在上面我们实现了RBAC权限设计思想的各个环节,,给用户添加角色,给角色添加了权限,相当
于实现了 员工拥有了权限点, 接下来我们就可以利用这些权限点做实际的权限控制,
在人资项目后台管理系统中,权限控制的地方有两个:
1. 左侧菜单权限控制 (不同的用户进来的系统之后,看到的菜单是不同的)
2. 操作按钮权限控制 (页面上的按钮,不同的人也有不同的权限)
如何修改权限数据?
使用管理员账号登录,然后给刚才创建的新员工分配俩个菜单权限和一个操作按钮权限,<br /> 然后我们再次登录员工账号查看个人信息返回数据<br /> 操作步骤:<br /> <br /> 1. 员工管理 > 给员工分配**人事总监**角色<br /> 2. 角色管理 > 新建角色**人事总监** > 给角色分配权限 (员工管理,导入,导出)<br /> 3. 权限点管理 > 给**员工管理**下增加导入,导出 按钮操作权限点<br /> 4. 重新登录新员工账号,查看权限数据,观察data.roles.menus, points项目
1. 动态生成左侧菜单 — addRoutes 方法
1) 分析: 登录成功(页面跳转),进入导航守卫:
. 获取个人权限信息
. 生成可以访问的动态路由
2) 思路:
用户能访问到的页面(路由配置)必须是动态的, 所以要先掌握一个可以动态添加路
由地址的API
addRoutes基本使用 *
作用:动态添加路由配置 ,从地址栏中访问页面: 动态生成可以访问的菜单,它不能保
证左侧菜单,左侧菜单是通过其他来设置的
router.addRoutes([路由配置对象])
或者:
this.$router.addRoutes([路由配置对象])
1. 在router/index.js中的路由配置中删除动态路由的部分
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
// routes: constantRoutes
// 合并动态和静态的路由 , ...asyncRoutes
- routes: [...constantRoutes, ...asyncRoutes]
+ routes: [...constantRoutes]
})
// constantRoutes 静态的 asyncRoutes 动态的
2. 在 路由守卫中 引入,并使用addRoutes动态添加
(把之前在router中直接静态写死的动态路由改造成通过addRoutes方法调用添加的形式)
// 引入所有的动态路由表(未经过筛选)
+ import router, { asyncRoutes } from '@/router'
const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {
// 开启进度条
NProgress.start()
// 获取本地token 全局getter
const token = store.getters.token
if (token) {
// 有token
if (to.path === '/login') {
next('/')
} else {
if (!store.getters.userId) {
await store.dispatch('user/getUserInfo')
// 改写成动态添加的方式
+ router.addRoutes(asyncRoutes)
}
next()
}
} else {
// 没有token
if (whiteList.includes(to.path)) {
next()
} else {
next('/login')
}
}
// 结束进度条
NProgress.done()
})
核心代码: router.addRoutes(asyncRoutes)
实现效果: 这个时候左侧菜单是没有的,只能通过地址来访问到其他的页面
2. 动态生成左侧菜单- 改写菜单保存位置 *
问题分析:
当前的菜单渲染(src\layout\components\Sidebar\index.vue)使用的数据:this.$router.options.routes 这个数据是固定,我们通过addRoutes添加的路由表只存在内存中,并不会改变this.$router.options.routes , 使用这个取得的路由, 是取不到的, 所以左侧菜单是空的
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625499114292-6ed2931a-ba40-4d97-ab1a-ff109f8c41b3.png#clientId=ub8aed2bc-b045-4&from=paste&height=133&id=u20f28522&margin=%5Bobject%20Object%5D&name=image.png&originHeight=133&originWidth=593&originalType=binary&ratio=1&size=13269&status=done&style=none&taskId=u639293cf-9a32-4ff3-a91e-ead476c6dbd&width=593)
解决:
我们希望在调用addRoutes方法之后,要路由数据立刻反映到菜单中,我们需要想一个的方
法,就是在vuex 中保存我们的菜单数据
目标: 在vuex 中保存菜单数据
落地代码: 将菜单数据保存在vuex中
1. 补充模块。在 src/store/modules下补充menu.js模块:
. 定义数据menuList
. 修改数据的方法setMenuList
// 导入静态路由
import { constantRoutes } from '@/router'
export default {
namespaced: true,
state: {
// 先以静态路由作为菜单数据的初始值
menuList: [...constantRoutes]
},
mutations: {
setMenuList(state, asyncRoutes) {
// 将动态路由和静态路由组合起来
state.menuList = [...constantRoutes, ...asyncRoutes]
}
}
}
要在src/store/index.js中注册这个模块
+ import menu from './modules/menu'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
settings,
user,
+ menu
},
getters
})
2. 提交setMenuList生成完整的菜单数据
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625499952909-d5655161-6d1c-40d4-86b8-140219676259.png#clientId=ub8aed2bc-b045-4&from=paste&height=103&id=u8d72eabc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=103&originWidth=444&originalType=binary&ratio=1&size=7878&status=done&style=none&taskId=u1b711da8-9ff3-405b-8694-685d772834d&width=444)
3. 菜单生成部分改写使用vuex中的数据(就是上面问题分析里面的)
这一步的作用就是:
把vuex里面的菜单数据拿出来,现在可以在左侧菜单中看见各个菜单了
routes() {
// 拿到的是一个完整的包含了静态路由和动态路由的数据结构
// return this.$router.options.routes
return this.$store.state.menu.menuList
}
4. 小结:
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625500112503-9c3ecd58-1732-4f1f-abb4-97dd11b90a34.png#clientId=ub8aed2bc-b045-4&from=paste&height=269&id=u4f4283bb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=269&originWidth=589&originalType=binary&ratio=1&size=31037&status=done&style=none&taskId=u42837259-7bcd-40a8-b691-ac6416703f1&width=589)
四: 权限应用 - 使用权限数据做过滤处理
目标: 上一步我们实现了:
把动态路由通过addRoutes动态添加到了路由系统里
把动态路由保存到vuex的menu中
但是我们没有和权限数据做搭配,接下来我们通过接口返回的权限数据对动态菜单(8个页面)做
过滤处理,以确定完成菜单与用户权限相关。
为什么做过滤作用:
我们需要的是: 得到个人的权限数据[‘setting’,’department’…],再保存到vuex中去, 而不是获取所有的菜单数据都保存到vuex中去,这样就做不成权限了(就不能每个用户能访问到不同的页面了)
落地代码:
1.
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625500731074-84815dd7-a121-41f3-b31b-39a7b564c318.png#clientId=ub8aed2bc-b045-4&from=paste&height=348&id=u5cbf85f3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=348&originWidth=491&originalType=binary&ratio=1&size=28925&status=done&style=none&taskId=u07ba8b25-af7c-448b-bbdc-5090729f6bc&width=491)<br />
2. 在permission.js中获取action的返回值并过滤
if (!store.getters.userId) {
// 有token,要去的不是login,就直接放行
// 进一步获取用户信息
// 发ajax---派发action来做
+ const menus = await store.dispatch('user/getUserInfo')
console.log('当前用户能访问的页面', menus) // ['salarys', 'settings']
console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)
// 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面
+ const filterRoutes = asyncRoutes.filter(route => {
+ const routeName = route.children[0].name
+ return menus.includes(routeName)
+ })
// 一定要在进入主页之前去获取用户信息
// addRoutes用来动态添加路由配置
// 只有在这里设置了补充了路由配置,才可能去访问页面
// 它们不会出现左侧
+ router.addRoutes(filterRoutes)
// 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue
// 生成左侧菜单时,也应该去vuex中拿
+ store.commit('menu/setMenuList', filterRoutes)
}
最终效果:
就是可以不同的人进来就有不同的权限了(能看到哪些页面)
<br />
五: 权限应用 - 按钮级的权限控制
说明: 上面我们已经完成了页面级别的权限控制,,现在我们要完成按钮级别的权限控制
目标: 员工A和员工B都可以访问同一个页面(以员工管理为例),但是员工A可以导出excel,员工
B就不可以导出excel
思路: 用户登陆成功后,用户可以访问的按钮级别权限保存在points数组中。而这个数据我们是保存
在vuex中的,所以,就可以在项目的任意地方来中访问。
如果某个按钮上的标识在points出现,则可以显示出来
1. 自定义指令:
解决按钮级别的权限验证
在main.js中 定义全局指令
// 注册一个全局自定义指令 `v-allow`
Vue.directive('allow', {
inserted: function(el, binding) {
// 从vuex中取出points,
const points = store.state.user.userInfo.roles.points
// 如果points有binding.value则显示
if (points.includes(binding.value)) {
// console.log('判断这个元素是否会显示', el, binding.value)
} else {
el.parentNode.removeChild(el)
// el.style.display = 'none'
}
}
})
使用:
<el-button
+ v-allow="'import_employee'"
type="warning"
size="small"
@click="$router.push('/import')"
>导入excel</el-button>
这里的: ‘import_employee’ 是从标识符来的
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625501414778-4a1323e4-c28a-4538-851d-908b560da0b0.png#clientId=ub8aed2bc-b045-4&from=paste&height=360&id=uacf45de9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=360&originWidth=451&originalType=binary&ratio=1&size=28648&status=done&style=none&taskId=u3d4ba754-c641-47eb-a8c7-8ae4a467d8a&width=451)
权限控制流程重点梳理总结——大总结
业务场景
公司里有不同的职能部门,都在用同一套系统 ,不一样部门的人员进入系统里面需要操作<br /> 的事情是不一样的, 必定需要根据不同的员工角色配置不同的权限<br /> ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625501473419-a34830bf-54b3-4f06-b16c-f3c1f4d7214b.png#clientId=ub8aed2bc-b045-4&from=paste&height=291&id=uf2956e9a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=291&originWidth=660&originalType=binary&ratio=1&size=65033&status=done&style=none&taskId=ueb699d90-b268-493f-99eb-4d9ff7748f2&width=660)
一种基于角色的设计思想
1. 给员工配置角色 (一个员工可以拥有多个角色)<br /> 2. 给角色配置权限点 (一个角色可以有多个权限点)<br /> 员工只要有了角色之后,就自动拥有了角色绑定的所有权限点
根据权限设计思想对应业务模块
1. 员工管理<br /> 2. 角色管理<br /> 3. 权限点管理(它是没有调整的余地的:它会严格与当前系统的功能对应!)
使用权限数据做具体的权限处理
菜单权限控制
登录 > 菜单权限数据 > 和本地的所有的动态路由数据做匹配出具 > 得到根据权限筛选之后的动态路由数据
- 添加到路由系统中 (可以根据路径标识渲染组件 addRoutes)
- 添加到左侧菜单渲染 (vuex管理 + v-for遍历)
按钮权限控制
登录 > 按钮权限数据 > 使用按钮单独的权限标识 去权限数据里面查找
刷新页面时的bug修复
问题
(1)如果我们刷新浏览器,会发现跳到了404页面<br /> (2)对于addRoute添加的路由,在刷新时会白屏
原因
现在我们的路由设置中的404页处在中间位置而不是所有路由的末尾了。
解决
把404页改到路由配置的最末尾就可以了
代码
从route/index.js中的静态路由中删除path:’*’这一项 ```javascript // 不需要特殊的权限控制就可以访问的页面 export const constantRoutes = [ { path: ‘/login’, component: () => import(‘@/views/login/index’), hidden: true },
// 404 page must be placed at the end !!!
- { path: ‘*’, redirect: ‘/404’, hidden: true } ]
2. 在permission.js中补充在最后
```javascript
// if(没有userInfo) {
if (!store.getters.userId) {
// 有token,要去的不是login,就直接放行
// 进一步获取用户信息
// 发ajax---派发action来做
const menus = await store.dispatch('user/getUserInfo')
console.log('当前用户能访问的页面', menus)
console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)
// 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面
const filterRoutes = asyncRoutes.filter(route => {
const routeName = route.children[0].name
return menus.includes(routeName)
})
// 一定要在进入主页之前去获取用户信息
// 把404加到最后一条
+ filterRoutes.push( // 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true })
// addRoutes用来动态添加路由配置
// 只有在这里设置了补充了路由配置,才可能去访问页面
// 它们不会出现左侧
router.addRoutes(filterRoutes)
// 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue
// 生成左侧菜单时,也应该去vuex中拿
store.commit('menu/setMenuList', filterRoutes)
}
3. 解决刷新出现的白屏bug (固定)
if (!store.getters.userId) {
// 省略其他...
// 解决刷新出现的白屏bug
next({
...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)
replace: true // 重进一次, 不保留重复历史
})
} else {
next()
}
退出时重置路由:
问题
退出后,再次登陆,发现菜单异常 (控制台有输出说路由重复);
原因
路由设置是通过router.addRoutes(filterRoutes)来添加的,退出时,并没有清空,再次登陆,又加了一次,所以有重复。
需要将路由权限重置 (恢复默认) 将来登录后再次追加才可以,不然的话,就会重复添加
解决
我们的router/index.js文件,发现一个重置路由方法
// 重置路由
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // 重新设置路由的可匹配路径
}
这个方法就是将路由重新实例化,相当于换了一个新的路由,之前**加的路由**就不存在了,需要在**登出的时候, 调用一下即可**
在store/modules/user.js
数据回填问题 : created只执行一次
原因
由于子组件在dialog嵌套,所以,它只会创建一次:created只执行一次,后续的显示隐藏操作,都不会导致组件重建,所以:后面打开的内容与第一次是一样的。
方案一: 让弹层隐藏时,把子组件销毁。
<el-dialog
title="分配角色"
:visible.sync="showDialogRole"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<子组件
+ v-if="showDialogAssign"
/>
</el-dialog>
优点:简单;取到的是最新的数据;
缺点:销毁组件,有一定性能问题,
方案二:通过refs来引用子组件,直接调用它的方法来发请求
给子组件添加引用
<assign-role
ref="assignRole"
:employee-id="curEmployeId"
@close="showDialogRole=false"
/>
获取子组件的引用, 调它的方法
![image.png](https://cdn.nlark.com/yuque/0/2021/png/21762447/1625502722985-32ac250d-2464-43b4-9dd0-47f5510c41c0.png#clientId=ub8aed2bc-b045-4&from=paste&height=117&id=u68d5e422&margin=%5Bobject%20Object%5D&name=image.png&originHeight=117&originWidth=535&originalType=binary&ratio=1&size=7975&status=done&style=none&taskId=ucd133ae2-bcc9-4213-a8e3-0f1035781d0&width=535)