Предисловие:
Требование: необходимо сопоставить разные права управления для разных пользователей, то есть сопоставить различную навигацию по операциям, особенно в фоновой системе управления, если она только не отображается в меню навигации, страницу все равно можно открыть напрямую через путь, потому что его информация о маршрутизации была зарегистрирована в объекте информации о маршрутизации (новый Router({})) функция
Конечно, глобальную навигационную защиту можно использовать для различения разных пользователей и предоставления им возможности входить по разным путям, но это можно использовать только для простого определения разрешений, а интерфейс написан до смерти, поэтому гибкость не высока, и его нельзя настроить для каждого пользователя.
адрес проекта:GitHub.com/sensor001/v UE-…
Добро пожаловать в звезду, может быть, вы сможете использовать ее, если сохраните ее.В конце концов, управление разрешениями все еще очень распространено.
используемые правила
1. Отображение пользовательского интерфейса для динамической настройки разрешений
Здесь используется элемент управления «Три дерева» element-ui Структура данных выглядит следующим образом:
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}]
Это древовидное управление выбрано здесь, потому что его структура данных очень близка к нашей зарегистрированной структуре информации о маршрутизации, и ее можно идеально отобразить в элементе управления «Три дерева» без повторного изменения структуры данных информации о маршрутизации.
2. Извлеките объекты информации о маршруте, необходимые для боковой навигации, в массив, отфильтруйте соответствующую информацию о маршруте в соответствии с массивом, возвращенным в фоновом режиме, и добавьте его к объекту информации о маршруте с помощью addRoutes, чтобы завершить динамическое добавление информации о маршруте.
Подробности
// 在router.js 路由文件 新建数组路由存储 '/' 父路由下的所有子路由(这里所有的动态路由均为 '/' 的子路由)
let routerLists=[
{
id:1,
path: '',
label: '首页',
redirect: '/index', //重定向到
meta:{
title: '首页',
table: true,
display: false,
icon: 'el-icon-s-home'
}
},
{
id: 2,
path: '/index',
name: 'index',
label: '首页',
component: _import('Index/Index'),
meta:{
title: '首页',
table: true,
display:true,
icon: 'el-icon-s-home'
}
},
{
id: 3,
path: '/shop',
name: 'shop',
label: '商品管理',
component: _import('Shop/Shop'),
meta:{
title: '商品列表',
table: true,
display:true,
icon: 'el-icon-s-operation'
}
},
{
id:20,
path: '/admin',
label: '管理员列表',
component: _import('admin/index'),
meta:{
title: '管理员列表',
table: true,
display:true,
icon: 'el-icon-s-custom'
},
children:[
{
id:21,
path: '/admin/index',
label: '管理员列表',
component: _import('admin/admin'),
meta:{
title: '管理员列表',
table: true,
display:true,
icon:'el-icon-tickets'
}
},
{
id:22,
path: '/admin/adminlist',
label: '添加管理员',
component: _import('admin/adminlist'),
meta:{
title: '添加管理员',
table: true,
display:true,
icon:'el-icon-document-remove'
}
}
]
}
]
//定义 上面数组的父路由
let routerAlls=[ //这里为routerLists的父路由
{
path: '/',
component: Home
}
]
1 .权限配置表
// 先把路由信息对象字符串化,然后去除component字段 ,再传递给 权限配置表
let routerListString =JSON.stringify(routerLists)
let src= routerListStr(routerListString)
store.commit('serRouterList',src)
let arr=[1,2,3,20,21,22] //这里为权限列表数组(既后台根据用户身份返回的对应的路由数组)
//根据权限配置表(arr数组)和动态路由信息对象(routerLists数组) 获取本用户的路由信息表,并添加到 routerAlls 路由的二级路由里
2.获取动态路由
routerAlls[0].children = routerListFun(arr,routerLists)
//获取 路径 '/' 的子路由,并添加至 routerAlls 这里的 routerListFun函数 为 根据权限列表数组(arr)筛选动态路由信息对象(routerLists) PS:函数内容见 文章末尾:附录
3.获取侧边导航栏 的 渲染菜单 数组
//根据权限配置表数组(arr)和动态路由信息对象(routerLists) 获取本用户的菜单列表
let mentParse =JSON.parse(JSON.stringify(src))
let menuList = routerListFun(arr,mentParse) //这里routerListFun函数注意去除返回数组中的component
store.commit('setMents',menuList) //将其添加到vuex
// 注册路由
let routers =new Router({
mode: 'history',
// base: process.env.BASE_URL,
routes: [
{
path: '/loading',
name: 'loading',
component: () => import('../views/Load/Loading.vue'),
meta:{
title: '登陆',
table: false
}
}
]
})
// 将筛选后的路由信息对象添加至路由表
routers.addRoutes(routerAlls)
// 进行全局导航守卫
routers.beforeEach((to,from,next)=>{
if(to.path != '/loading'){
let username=store.state.load.userList.username
if(username){
next()
}else{
next({
path:'/loading',
query:{
path:to.path
}
})
}
}else{
next()
}
})
export default routers;
приложение
1. Правила написания динамической маршрутизации
* 路由书写规则
* 1、只有一级路由(实际为二级路由):
* {
id: 2, //ID全局不能重复
path: '/index', //路由路径 全局不能重复
name: 'index', //名字,全局不能重复,存在二级路由,则一级路由不能有名字
label: '首页', // 页面名称(用于权限配置时 显示名称使用)
component: _import('Index/Index'), // 文件地址(此处对应的是views目录)
meta:{
title: '首页', //页面名称(横向teble标签切换)
table: true, // 是否显示 teable 切换按钮
display:true, // 是否在侧边导航菜单显示
icon: 'el-icon-s-home' // 侧边导航的icon图标
}
}
2、包含二级路由(实际为三级路由)
{
id:20, //ID全局不能重复
path: '/admin', //路由路径 全局不能重复(此处为父级))
label: '管理员列表', // 页面名称(用于权限配置时 显示名称使用)
component: _import('admin/index'), // 文件地址(此处对应的是views目录)注意:此文件下 应包含(router-view 标签 来显示子页面)
meta:{
title: '管理员列表', //页面名称(横向teble标签切换)
table: true,
display:true, // 是否在侧边导航菜单显示(注意 这里是父级,如果为false,则子级不在折叠)
icon: 'el-icon-s-custom' // 侧边导航的icon图标
},
children:[
{
id:21, //ID全局不能重复
path: '/admin/index', //路由路径 全局不能重复(此处为父级))
label: '管理员列表', // 页面名称(用于权限配置时 显示名称使用)
component: _import('admin/admin'), // 文件地址(此处对应的是views目录)
meta:{
title: '管理员列表', //页面名称(横向teble标签切换)
table: true, // 是否显示 teable 切换按钮
display:true, // 是否在侧边导航菜单显示
icon:'el-icon-tickets' // 侧边导航的icon图标
}
}
]
}
2. Функция RouterlistFun, RouterListStr
// 根据后台返回的权限数组,筛选对应的路由信息对象
export function routerListFun(arr,allList){
let arrArray=[]
for(let i=0;i<arr.length;i++){
for(let k=0;k<allList.length;k++){
if(arr[i] == allList[k].id){
arrArray.push(allList[k])
}
}
}
for(let i=0;i<arrArray.length;i++){
if(arrArray[i].children && arrArray[i].children.length>0){
arrArray[i].childrens=[]
for(let k=0;k<arrArray[i].children.length;k++){
for(let j=0;j<arr.length;j++){
if(arrArray[i].children[k].id == arr[j]){
arrArray[i].childrens.push(arrArray[i].children[k])
}
}
}
arrArray[i].children=arrArray[i].childrens
}
}
return arrArray;
}
// 根据全部的路由信息对象 返回 权限列表
export function routerListStr(routerStr){
let routerJson= JSON.parse(routerStr)
for(let i=0;i<routerJson.length;i++){
if(routerJson[i].component){
routerJson[i].component=''
}
if(routerJson[i].children && routerJson[i].children.length>0){
for(let k=0;k<routerJson[i].children.length;k++){
routerJson[i].children[k].component=''
}
}
}
return routerJson;
}
3. Отрисовка маршрута
<!-- 这里的 routerList 为 从 router.js动态获取到了路由信息 -->
<div v-for="item in routerList" :key="item.id" >
<!--包含二级导航-->
<el-submenu :index="item.id.toString()" v-if="item.children && item.children.length > 0 && item.meta.display==true">
<template slot="title">
<i :class="item.meta.icon"></i>
<span>{{item.label}}</span>
</template>
<el-menu-item v-show="items.meta.display" v-for="(items,indexs) in item.children" :key="indexs" :index="items.path">
<i :class="items.meta.icon"></i>
{{items.label}}
</el-menu-item>
</el-submenu>
<!-- 如果 二级导航的 父级 设置display:false 则直选渲染二级导航为一级导航 -->
<el-menu-item v-for="(items,indexs) in item.children" :key="indexs" :index="items.path" v-show="items.meta.display" v-else-if="item.children && item.children.length > 0 && item.meta.display==false" >
<i :class="item.meta.icon"></i>
<span slot="title">{{item.label}}</span>
</el-menu-item>
<!-- 渲染一级导航 -->
<el-menu-item v-show="item.meta.display" :index="item.path" v-else >
<i :class="item.meta.icon"></i>
<span slot="title">{{item.label}}</span>
</el-menu-item>
</div>