路由权限的实现与动态导航的渲染
1. 作用
- 对于管理系统,不同的账号有不同的权限,登录后所看到的内容自然也应该不同。
- 所以这里就要根据账号的角色渲染不同的导航,有些路由就不能访问。
2. 处理路由,形成不同的权限。
1. 拆分路由
- 把路由拆分成不同的模块,每个模块能访问到的路由是不同的,至于超级管理员这种应该能查看所有路由。
- 这里为了简单演示,就分两个,以便日后查看与理解。
// 1: 普通管理员路由
const normalRoutes = [
// 默认进入登录页
{ path: '/', redirect: '/login' },
{ path: '/login', component: () => import('@/views/login/Login.vue') },
// 首页
{
path: '/home', meta: { title: '首页' }, isMenu: true, icon: 'el-icon-s-home', component: () => import('@/views/home/Layerout.vue'),
children: [
{ path: '', component: () => import('@/views/home/Home.vue') }
]
},
// 要展示导航的路由添加自定义属性:isMuse,
// 商品模块
{
path: '/goods', meta: { title: '商品管理' }, icon: 'el-icon-sell', isMenu: true, component: () => import('@/views/home/Layerout.vue'), redirect: '/goods/list',
children: [
{ path: '/goods/list', meta: { title: '商品列表' }, isMenu: true, component: () => import('@/views/goods/GoodsList.vue') },
{ path: '/goods/add', meta: { title: '商品添加' }, isMenu: true, component: () => import('@/views/goods/GoodsAdd.vue') },
]
},
// 订单管理
{
path: '/order', meta: { title: '订单管理' }, icon: 'el-icon-document', isMenu: true, component: () => import('@/views/home/Layerout.vue'),
children: [
{ path: '', component: () => import('@/views/order/Order.vue') }
]
},
]
// 2: 超级管理员路由
const superRoutes = [
// 账号模块
{
path: '/account', icon: 'el-icon-user-solid', meta: { title: '账号管理' }, isMenu: true, component: () => import('@/views/home/Layerout.vue'), redirect: '/account/list',
children: [
//这里是多个子路由。
]
},
// 店铺管理
{
path: '/store', icon: 'el-icon-s-shop', meta: { title: '店铺管理' }, isMenu: true, component: () => import('@/views/home/Layerout.vue'),
children: [
{ path: '', component: () => import('@/views/store/Store.vue') }
]
},
]
- 上面的注意点
- meta属性的title是用来记录
路径名字的
,以便后面调用。 - isMenu属性是用来判断要不要显示到导航上,后面可以利用这个属性
踢出不用的路由
。 - icon是element图标的名字
2. 封装函数用以返回不同的路由集合
- 函数内从本地读取当前账号角色分类,当然也可以不用本地读取。
let role = local.get('role')
- 根据不同账号返回不同路由,
注意这里要暴露出去
,因为导航栏还要使用到这些路由。
//返回路由的函数
export function showRoute() {
let role = local.get('role')
//超级管理员返回所有路由
if (role === 'super') {
return [...normalRoutes, ...superRoutes]
//普通管理员返回普通路由
} else {
return normalRoutes
}
}
3. 路由实例化时调用函数
const router = new VueRouter({
routes: showRoute()
})
这样就实现了不同类型账号
能够读取不同的路由
。
路由权限就实现了
。
3. 导航的动态渲染
1. 导航栏获取路由数据
- 引入上面暴露的路由函数
// 引入渲染导航的函数
import { showRoute } from "@/router/index.js";
- 筛选出拥有自定义属性isMenu的路由
export default {
data() {
return {
routes: showRoute().filter(v => v.isMenu)
};
}
};
2. 进行渲染
利用这个获取到的数据渲染一级导航。
- 因为v-for和v-if写到同一个标签上编码软件会报错,实际上是可以运行的。所以要用一个template的虚拟标签来,这里的:key可以写到内部,因为他是个虚拟标签。
<template v-for="(v, i) in routes"></template>
- 在里面渲染标签,
v-if进行判断v.children.length是不是1
,如果是就渲染一级导航。
<!-- 只有一层的菜单 -->
<el-menu-item :index="v.path" :key="i" v-if="v.children.length===1">
<i :class="v.icon"></i>
<span slot="title">{{ v.meta.title }}</span>
</el-menu-item>
- 紧接着写
v-else
二级菜单,因为路由里面还有children也要进行遍历与判断,所以还要用到虚拟标签。 - v-for进行遍历,v-if对取出的值进行判断,如果有isMenu就创建他。
<!-- 两层的菜单,第一层 -->
<el-submenu :index="v.path" v-else :key="i">
<template slot="title">
<i :class="v.icon"></i>
<span>{{ v.meta.title }}</span>
</template>
<el-menu-item-group>
<!-- 第二层 -->
<template v-for="(n, j) in v.children">
<el-menu-item :index="n.path" v-if="n.meta" :key="j">{{ n.meta.title }}</el-menu-item>
</template>
</el-menu-item-group>
</el-submenu>
- 这样就利用路由实现了导航的动态渲染。
4. 解决单页应用的一个bug
- 不同账号在同一设备登录可能会查看到不属于自己权限的内容。必须要刷新一次。
- 因为跳转页面的函数是异步的,所以添加await。
// 登陆成功时
if (res.data.code === 0) {
// 存储数据
local.set("token", res.data.token);
// 储存角色
local.set("role", res.data.role);
// 跳转页面
await this.$router.push("/home");
// 解决不同账号登录的bug,会访问到不该访问的页面
window.location.reload();
}
标签:views,渲染,component,meta,path,import,权限,路由
From: https://www.cnblogs.com/lyc00000000/p/17460350.html