vue权限控制——动态路由

本文续接上一篇博客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'vue权限控制——动态路由

 修改路由配置

通过上一篇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()
  }
}

完成了 

上一篇:Vue 自定义级联菜单


下一篇:Oracle转PostgreSQL之start with / connect by