关于vue中根据用户权限动态添加路由的问题
作者:一只烛 发布时间:2024-05-05 09:25:11
标签:vue,动态添加路由,用户权限
根据用户的权限,展示不同的菜单页。
知识点
路由守卫(使用了前置守卫):根据用户角色判断要添加的路由
vuex:保存动态添加的路由
难点
每次路由发生变化时都需要调用一次路由守卫,并且store中的数据会在每次刷新的时候清空,因此需要判断store中是否有添加的动态路由。
(若没有判断 则会一直添加 导致内存溢出)
根据角色判断路由
过滤动态路由 判断每条路由角色是否与登录传入的角色一致
<template>
<div>
<el-menu
:default-active="$route.path"
class="el-menu-vertical-demo menu_wrap"
background-color="#324057"
text-color="white"
active-text-color="#20a0ff"
:collapse="isCollapse"
unique-opened
router
>
<el-submenu
v-for="item in $store.state.Routers"
:key="item.path"
:index="item.path"
v-if="!item.hidden"
>
<template slot="title" >
<i class="el-icon-location"></i>
<span>{{ item.meta.title }}</span>
</template>
<div v-for="chi in item.children" :key="chi.name">
<el-menu-item v-if="!chi.hidden" :index="item.path + '/' + chi.path">
<i class="el-icon-location"></i>{{ chi.meta.title }}
</el-menu-item>
</div>
</el-submenu>
</el-menu>
</div>
</template>
<script>
export default {
name: "MenuList",
data() {
return {
isCollapse: false,
};
},
created() {
this.$bus.$on("getColl", (data) => {
this.isCollapse = data;
});
},
methods: {
}
};
</script>
<style scoped>
.menu_wrap {
height: 100vh;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
height: 100vh;
}
</style>
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '../store/index'
Vue.use(VueRouter)
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
export const routes = [
{
path: '/home',
name: 'First',
component: () => import('../views/Index.vue'),
meta: { title: 'Home'},
children: [
{
path: 'index',
name: 'Home',
component: () => import('../views/Home'),
meta: { title: 'Home', roles: ['Customer'] }
}
]
},
{
path: '/index',
name: 'NavigationOne',
component: () => import('../views/Index.vue'),
meta: { title: '导航一'},
children: [
{
path: 'personnel',
name: 'Personnel ',
component: () => import('../views/One/Personnel.vue'),
meta: { title: 'Personnel', roles: ['Customer'] }
},
{
path: 'account',
name: 'Account',
component: () => import('../views/One/Account.vue'),
meta: { title: 'Account', roles: ['Customer'] }
},
{
path: 'psw',
name: 'psw',
component: () => import('../views/One/Password.vue'),
meta: { title: 'psw', roles: ['Customer'] }
}
]
},
{
path: '/card',
name: 'NavigationTwo',
component: () => import('../views/Index.vue'),
meta: { title: '导航二'},
children: [
{
path: 'activity',
name: 'Activity ',
component: () => import('../views/Three/Activity.vue'),
meta: { title: 'Activity', roles: ['Customer'] }
},
{
path: 'Social',
name: 'Social',
component: () => import('../views/Three/Social.vue'),
meta: { title: 'Social', roles: ['Customer'] }
},
{
path: 'content',
name: 'Content',
component: () => import('../views/Three/Content.vue'),
meta: { title: 'Content', roles: ['Customer'] }
}
]
},
{
path: '/two',
name: 'NavigationThree',
component: () => import('../views/Index.vue'),
meta: { title: '导航三'},
children: [
{
path: 'index',
name: 'Two ',
component: () => import('../views/Two'),
meta: { title: 'Two', roles: ['Customer'] }
}]
},
{
path: '/404',
name: 'Error',
hidden: true,
meta: { title: 'error'},
component: () => import('../views/Error')
}
]
export const asyncRouter = [
// Agent3 Staff2
{
path: '/agent',
component: () => import('../views/Index.vue'),
name: 'Agent',
meta: { title: 'Agent', roles: ['Agent','Staff']},
children: [
{
path: 'one',
name: 'agentOne',
component: () => import('@/views/agent/One'),
meta: { title: 'agentOne', roles: ['Agent','Staff'] }
},
{
path: 'two',
name: 'agentTwo',
component: () => import('@/views/agent/Two'),
meta: { title: 'agentTwo', roles: ['Agent'] }
},
{
path: 'three',
name: 'agentThree',
component: () => import('@/views/agent/Three'),
meta: { title: 'agentThree', roles: ['Agent','Staff'] }
}
]
},
// Staff3
{
path: '/staff',
component: () => import('../views/Index.vue'),
name: 'Staff',
meta: { title: 'Staff', roles: ['Staff']},
children: [
{
path: 'one',
name: 'StaffOne',
component: () => import('@/views/Staff/One'),
meta: { title: 'StaffOne', roles: ['Staff'] }
},
{
path: 'two',
name: 'StaffTwo',
component: () => import('@/views/Staff/Two'),
meta: { title: 'StaffTwo', roles: ['Staff'] }
},
{
path: 'three',
name: 'StaffThree',
component: () => import('@/views/Staff/Three'),
meta: { title: 'StaffThree', roles: ['Staff'] }
}
]
},
{ path: '*', redirect: '/404', hidden: true }
]
const router = new VueRouter({
routes
})
router.beforeEach((to, from, next) =>{
let roles = ['Staff']
if(store.state.Routers.length) {
console.log('yes')
next()
} else {
console.log('not')
store.dispatch('asyncGetRouter', {roles})
.then(res =>{
router.addRoutes(store.state.addRouters)
})
next({...to})
// next()与next({ ...to })的区别:next() 放行 next('/XXX') 无限拦截
}
})
export default router
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './module'
import router, {routes, asyncRouter} from '../router'
function hasPermission(route, roles) {
if(route.meta && route.meta.roles) {
return roles.some(role =>route.meta.roles.indexOf(role) >= 0)
} else {
return true
}
}
/*
递归过滤异步路由表 返回符合用户角色的路由
@param asyncRouter 异步路由
@param roles 用户角色
*/
function filterAsyncRouter(asyncRouter, roles) {
let filterRouter = asyncRouter.filter(route =>{
if(hasPermission(route, roles)) {
if(route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, roles)
}
return true
}
return false
})
return filterRouter
}
Vue.use(Vuex)
export default new Vuex.Store({
state: {
addRouters: [],
Routers: []
},
mutations: {
getRouter(state, paload) {
// console.log(paload)
state.Routers = routes.concat(paload)
state.addRouters = paload
// router.addRoutes(paload)
}
},
actions: {
asyncGetRouter({ commit }, data) {
const { roles } = data
return new Promise(resolve =>{
let addAsyncRouters = filterAsyncRouter(asyncRouter, roles)
commit('getRouter', addAsyncRouters)
resolve()
})
}
}
})
来源:https://blog.csdn.net/weixin_44813417/article/details/121144909


猜你喜欢
- 一、问题描述define function,calculate the input parameters and return the re
- 1.奇偶校验我们约定一串编码里1的个数是偶数个,那么这串编码里携带的信息就是对的,否则就是错的。我们可以在开头对这串编码加一位校验码实现奇偶
- PNG格式以支持透明和无损,且相对大小适中,已成为现在网页中图片运用的主流。有些时候我们在制作网页时使用PNG格式图片,用IE浏览器查看却无
- 一、使用全局变量保存单例这是最简单的实现方法function Person(){ this.createTime=new Da
- 本文实例讲述了python判断一个集合是否包含了另外一个集合中所有项的方法。分享给大家供大家参考。具体如下:>>> L1
- windows下mysql双向同步备份实现方法以下的文章主要讲述的是在windows环境下实现MySQL数据库的主从同步备份的正确操作方案,
- 导言概述插入、更新和删除数据 里我们已经学习了如何使用GridView等控件来插入,更新删除数据。通过ObjectDataSource和其它
- Paddle模型性能分析Profiler定位性能瓶颈点优化程序提升性能Paddle Profiler是飞桨框架自带的低开销性能分析器,可以对
- 我就废话不多说了,大家还是直接看代码吧~#!/usr/bin/env python# -*- coding: utf-8 -*-import
- 也许还有朋友不太清楚DOMContentLoaded这个事件。简单的说,这个事件就是要在大多数情况下去替代window.onload事件,因
- 目录准备xlrd 读取 Excelxlwt 写入 Excel进阶用法最后准备使用 Python 操作 Excel 文件,常见的方式如下:xl
- Python docx库代码演示安装需要lxml pip install python-docx主业务代码from openpyxl imp
- a1="sp2=20;sp1=34;" a2="sp3=2;sp2=3;sp1=4;" 两组字符串数
- 一、使用ddt和data装饰器的大致框架如下,每个test_开头的方法,代表一条测试用例from ddt import ddt,dataim
- 昨天在W3C看到,6月10日发布了新的 HTML 5 草案(Working Draft)。粗略的读了一下它提供的 新版本说明文档 ,作了一点
- 一、旧式的字符串格式化% 操作符参考以下示例:>>> name = "Eric">>>
- 关于JavaSctipt的兼容性,最懒的办法就是用jQuery的工具函数。尽量不要用那些什么ECMAScript之类的函数,因为很多浏览器都
- 微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号)声明•微信小程序开发工具类似于一个轻量级的IDE集成开发环境,
- 写在前面最近写周赛题, 逃不开的一种题型是设计数据结构, 也就是第三题, 做这种题需要的就是对语言中的容器以及常用排序查找算法的掌握, 而我
- 在定义类的过程中,无论是显式创建类的构造方法,还是向类中添加实例方法,都要求将 self 参数作为方法的第一个参数。例如,定义一个 Pers