了解什么是RBAC权限设计思想

  1. ![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个页面,每个页面上的有不同的操作)
   角色:不同的权限点的集合  

   图示说明:

image.png

3. 如何给用户添加功能:

给用户分配角色,给角色分配权限点 (看上面那张图)

4. 系统中的权限点可以随意添加吗?

  1. 不能。必须是程序员已经开发出来的功能!!

5. 小结:


1. RBAC解决什么问题: 不同的人,有不同功能~
2. role-based access control
3. 三个主体: 用户 , 角色 , 权限点


真正的步骤来了 , 看下面

  1. 核心思想: 给员工分配角色,给角色分配权限,这样员工就有权限了

一: 给员工分配角色

1. 封装弹层组件

  1. 中间的步骤我就省了, 大概思路罗列到这里

目标: 在员工管理页面中,点击分配角色时,以弹层的方式打开/关闭组件

步骤: 封装组件,注册并且使用组件

子组件

image.png

背景:

  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属性决定了选中这一项之后值

image.png image.png

在模板中渲染:

image.png image.png

小结: el-checkbox-group v-model=”数组”

4. 员工获取数据并回填

目标:

如果当前用户已经配置过一些角色数据,应该先把已经配置过的角色数据回显出来:

有些checkbox是选中的!

  1. ![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. 保存

目标: 调用接口,将用户修改后的角色保存下来

思路:

封装接口 -> 调用接口

保存成功,要通知父组件关闭弹层


二: 给角色分配权限

为什么要给角色分配权限?

  1. 用户是什么角色(职位),他就具备某些功能<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 的属性

  1. ![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 处于选中状态

  1. ![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列表

  1. ![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. 操作按钮权限控制 (页面上的按钮,不同的人也有不同的权限)

如何修改权限数据?

  1. 使用管理员账号登录,然后给刚才创建的新员工分配俩个菜单权限和一个操作按钮权限,<br /> 然后我们再次登录员工账号查看个人信息返回数据<br /> 操作步骤:<br /> <br /> 1. 员工管理 > 给员工分配**人事总监**角色<br /> 2. 角色管理 > 新建角色**人事总监** > 给角色分配权限 (员工管理,导入,导出)<br /> 3. 权限点管理 > 给**员工管理**下增加导入,导出 按钮操作权限点<br /> 4. 重新登录新员工账号,查看权限数据,观察data.roles.menus, points项目

1. 动态生成左侧菜单 — addRoutes 方法

1) 分析: 登录成功(页面跳转),进入导航守卫:

. 获取个人权限信息

. 生成可以访问的动态路由

2) 思路:

用户能访问到的页面(路由配置)必须是动态的, 所以要先掌握一个可以动态添加路

由地址的API

addRoutes基本使用 *

作用:动态添加路由配置 ,从地址栏中访问页面: 动态生成可以访问的菜单,它不能保

证左侧菜单,左侧菜单是通过其他来设置的

  1. router.addRoutes([路由配置对象])
  2. 或者:
  3. this.$router.addRoutes([路由配置对象])

1. 在router/index.js中的路由配置中删除动态路由的部分

  1. const createRouter = () => new Router({
  2. // mode: 'history', // require service support
  3. scrollBehavior: () => ({ y: 0 }),
  4. // routes: constantRoutes
  5. // 合并动态和静态的路由 , ...asyncRoutes
  6. - routes: [...constantRoutes, ...asyncRoutes]
  7. + routes: [...constantRoutes]
  8. })
  9. // constantRoutes 静态的 asyncRoutes 动态的

2. 在 路由守卫中 引入,并使用addRoutes动态添加

  1. (把之前在router中直接静态写死的动态路由改造成通过addRoutes方法调用添加的形式)
  1. // 引入所有的动态路由表(未经过筛选)
  2. + import router, { asyncRoutes } from '@/router'
  3. const whiteList = ['/login', '/404']
  4. router.beforeEach(async(to, from, next) => {
  5. // 开启进度条
  6. NProgress.start()
  7. // 获取本地token 全局getter
  8. const token = store.getters.token
  9. if (token) {
  10. // 有token
  11. if (to.path === '/login') {
  12. next('/')
  13. } else {
  14. if (!store.getters.userId) {
  15. await store.dispatch('user/getUserInfo')
  16. // 改写成动态添加的方式
  17. + router.addRoutes(asyncRoutes)
  18. }
  19. next()
  20. }
  21. } else {
  22. // 没有token
  23. if (whiteList.includes(to.path)) {
  24. next()
  25. } else {
  26. next('/login')
  27. }
  28. }
  29. // 结束进度条
  30. NProgress.done()
  31. })

核心代码: router.addRoutes(asyncRoutes)

实现效果: 这个时候左侧菜单是没有的,只能通过地址来访问到其他的页面


2. 动态生成左侧菜单- 改写菜单保存位置 *

问题分析:

当前的菜单渲染(src\layout\components\Sidebar\index.vue)使用的数据:this.$router.options.routes 这个数据是固定,我们通过addRoutes添加的路由表只存在内存中,并不会改变this.$router.options.routes , 使用这个取得的路由, 是取不到的, 所以左侧菜单是空的

  1. ![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 中保存菜单数据

image.png

落地代码: 将菜单数据保存在vuex中

1. 补充模块。在 src/store/modules下补充menu.js模块:

. 定义数据menuList

. 修改数据的方法setMenuList

  1. // 导入静态路由
  2. import { constantRoutes } from '@/router'
  3. export default {
  4. namespaced: true,
  5. state: {
  6. // 先以静态路由作为菜单数据的初始值
  7. menuList: [...constantRoutes]
  8. },
  9. mutations: {
  10. setMenuList(state, asyncRoutes) {
  11. // 将动态路由和静态路由组合起来
  12. state.menuList = [...constantRoutes, ...asyncRoutes]
  13. }
  14. }
  15. }

要在src/store/index.js中注册这个模块

  1. + import menu from './modules/menu'
  2. Vue.use(Vuex)
  3. const store = new Vuex.Store({
  4. modules: {
  5. app,
  6. settings,
  7. user,
  8. + menu
  9. },
  10. getters
  11. })

2. 提交setMenuList生成完整的菜单数据

  1. ![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里面的菜单数据拿出来,现在可以在左侧菜单中看见各个菜单了


  1. routes() {
  2. // 拿到的是一个完整的包含了静态路由和动态路由的数据结构
  3. // return this.$router.options.routes
  4. return this.$store.state.menu.menuList
  5. }

4. 小结:

  1. ![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.

  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的返回值并过滤

  1. if (!store.getters.userId) {
  2. // 有token,要去的不是login,就直接放行
  3. // 进一步获取用户信息
  4. // 发ajax---派发action来做
  5. + const menus = await store.dispatch('user/getUserInfo')
  6. console.log('当前用户能访问的页面', menus) // ['salarys', 'settings']
  7. console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)
  8. // 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面
  9. + const filterRoutes = asyncRoutes.filter(route => {
  10. + const routeName = route.children[0].name
  11. + return menus.includes(routeName)
  12. + })
  13. // 一定要在进入主页之前去获取用户信息
  14. // addRoutes用来动态添加路由配置
  15. // 只有在这里设置了补充了路由配置,才可能去访问页面
  16. // 它们不会出现左侧
  17. + router.addRoutes(filterRoutes)
  18. // 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue
  19. // 生成左侧菜单时,也应该去vuex中拿
  20. + store.commit('menu/setMenuList', filterRoutes)
  21. }

最终效果:

就是可以不同的人进来就有不同的权限了(能看到哪些页面)


  1. <br />

五: 权限应用 - 按钮级的权限控制

说明: 上面我们已经完成了页面级别的权限控制,,现在我们要完成按钮级别的权限控制

目标: 员工A和员工B都可以访问同一个页面(以员工管理为例),但是员工A可以导出excel,员工

B就不可以导出excel

思路: 用户登陆成功后,用户可以访问的按钮级别权限保存在points数组中。而这个数据我们是保存

在vuex中的,所以,就可以在项目的任意地方来中访问。

如果某个按钮上的标识在points出现,则可以显示出来

1. 自定义指令:

解决按钮级别的权限验证

在main.js中 定义全局指令

  1. // 注册一个全局自定义指令 `v-allow`
  2. Vue.directive('allow', {
  3. inserted: function(el, binding) {
  4. // 从vuex中取出points,
  5. const points = store.state.user.userInfo.roles.points
  6. // 如果points有binding.value则显示
  7. if (points.includes(binding.value)) {
  8. // console.log('判断这个元素是否会显示', el, binding.value)
  9. } else {
  10. el.parentNode.removeChild(el)
  11. // el.style.display = 'none'
  12. }
  13. }
  14. })

使用:

  1. <el-button
  2. + v-allow="'import_employee'"
  3. type="warning"
  4. size="small"
  5. @click="$router.push('/import')"
  6. >导入excel</el-button>

这里的: ‘import_employee’ 是从标识符来的

  1. ![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)

权限控制流程重点梳理总结——大总结

业务场景

  1. 公司里有不同的职能部门,都在用同一套系统 ,不一样部门的人员进入系统里面需要操作<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. 1. 给员工配置角色 (一个员工可以拥有多个角色)<br /> 2. 给角色配置权限点 (一个角色可以有多个权限点)<br /> 员工只要有了角色之后,就自动拥有了角色绑定的所有权限点

根据权限设计思想对应业务模块

  1. 1. 员工管理<br /> 2. 角色管理<br /> 3. 权限点管理(它是没有调整的余地的:它会严格与当前系统的功能对应!)

使用权限数据做具体的权限处理

  1. 菜单权限控制

    1. 登录 > 菜单权限数据 > 和本地的所有的动态路由数据做匹配出具 > 得到根据权限筛选之后的动态路由数据
    1. 添加到路由系统中 (可以根据路径标识渲染组件 addRoutes
    2. 添加到左侧菜单渲染 (vuex管理 + v-for遍历)
  2. 按钮权限控制

    1. 登录 > 按钮权限数据 > 使用按钮单独的权限标识 去权限数据里面查找


刷新页面时的bug修复

问题

  1. (1)如果我们刷新浏览器,会发现跳到了404页面<br /> (2)对于addRoute添加的路由,在刷新时会白屏

原因

现在我们的路由设置中的404页处在中间位置而不是所有路由的末尾了。

解决

把404页改到路由配置的最末尾就可以了

代码

  1. 从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 } ]
  1. 2. permission.js中补充在最后
  2. ```javascript
  3. // if(没有userInfo) {
  4. if (!store.getters.userId) {
  5. // 有token,要去的不是login,就直接放行
  6. // 进一步获取用户信息
  7. // 发ajax---派发action来做
  8. const menus = await store.dispatch('user/getUserInfo')
  9. console.log('当前用户能访问的页面', menus)
  10. console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)
  11. // 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面
  12. const filterRoutes = asyncRoutes.filter(route => {
  13. const routeName = route.children[0].name
  14. return menus.includes(routeName)
  15. })
  16. // 一定要在进入主页之前去获取用户信息
  17. // 把404加到最后一条
  18. + filterRoutes.push( // 404 page must be placed at the end !!!
  19. { path: '*', redirect: '/404', hidden: true })
  20. // addRoutes用来动态添加路由配置
  21. // 只有在这里设置了补充了路由配置,才可能去访问页面
  22. // 它们不会出现左侧
  23. router.addRoutes(filterRoutes)
  24. // 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue
  25. // 生成左侧菜单时,也应该去vuex中拿
  26. store.commit('menu/setMenuList', filterRoutes)
  27. }

3. 解决刷新出现的白屏bug (固定)

  1. if (!store.getters.userId) {
  2. // 省略其他...
  3. // 解决刷新出现的白屏bug
  4. next({
  5. ...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)
  6. replace: true // 重进一次, 不保留重复历史
  7. })
  8. } else {
  9. next()
  10. }

退出时重置路由:

问题

退出后,再次登陆,发现菜单异常 (控制台有输出说路由重复);

image.png

原因

路由设置是通过router.addRoutes(filterRoutes)来添加的,退出时,并没有清空,再次登陆,又加了一次,所以有重复。
需要将路由权限重置 (恢复默认) 将来登录后再次追加才可以,不然的话,就会重复添加

解决

我们的router/index.js文件,发现一个重置路由方法

  1. // 重置路由
  2. export function resetRouter() {
  3. const newRouter = createRouter()
  4. router.matcher = newRouter.matcher // 重新设置路由的可匹配路径
  5. }

  1. 这个方法就是将路由重新实例化,相当于换了一个新的路由,之前**加的路由**就不存在了,需要在**登出的时候, 调用一下即可**

在store/modules/user.js
image.png


数据回填问题 : created只执行一次

原因

由于子组件在dialog嵌套,所以,它只会创建一次:created只执行一次,后续的显示隐藏操作,都不会导致组件重建,所以:后面打开的内容与第一次是一样的。

解决

方案一: 让弹层隐藏时,把子组件销毁。

  1. <el-dialog
  2. title="分配角色"
  3. :visible.sync="showDialogRole"
  4. :close-on-click-modal="false"
  5. :close-on-press-escape="false"
  6. >
  7. <子组件
  8. + v-if="showDialogAssign"
  9. />
  10. </el-dialog>

优点:简单;取到的是最新的数据;
缺点:销毁组件,有一定性能问题,

方案二:通过refs来引用子组件,直接调用它的方法来发请求

给子组件添加引用

  1. <assign-role
  2. ref="assignRole"
  3. :employee-id="curEmployeId"
  4. @close="showDialogRole=false"
  5. />

获取子组件的引用, 调它的方法

  1. ![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)

这里的 loadRoles() 是子组件发的请求,获取数据列表啥的请求,去更新页面的