路由权限的实现与动态导航的渲染

路由权限的实现与动态导航的渲染

1. 作用

  1. 对于管理系统,不同的账号有不同的权限,登录后所看到的内容自然也应该不同。
  2. 所以这里就要根据账号的角色渲染不同的导航,有些路由就不能访问。

2. 处理路由,形成不同的权限。

1. 拆分路由

  1. 把路由拆分成不同的模块,每个模块能访问到的路由是不同的,至于超级管理员这种应该能查看所有路由。
  2. 这里为了简单演示,就分两个,以便日后查看与理解。
// 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') }
]
},
]
  1. 上面的注意点
  • meta属性的title是用来记录路径名字的,以便后面调用。
  • isMenu属性是用来判断要不要显示到导航上,后面可以利用这个属性踢出不用的路由
  • icon是element图标的名字

2. 封装函数用以返回不同的路由集合

  1. 函数内从本地读取当前账号角色分类,当然也可以不用本地读取。
let role = local.get('role')
  1. 根据不同账号返回不同路由,注意这里要暴露出去,因为导航栏还要使用到这些路由。
//返回路由的函数
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. 导航栏获取路由数据

  1. 引入上面暴露的路由函数
// 引入渲染导航的函数
import { showRoute } from "@/router/index.js";
  1. 筛选出拥有自定义属性isMenu的路由
export default {
data() {
return {
routes: showRoute().filter(v => v.isMenu)
};
}
};

2. 进行渲染

利用这个获取到的数据渲染一级导航。

  1. 因为v-for和v-if写到同一个标签上编码软件会报错,实际上是可以运行的。所以要用一个template的虚拟标签来,这里的:key可以写到内部,因为他是个虚拟标签。
<template v-for="(v, i) in routes"></template>
  1. 在里面渲染标签,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>
  1. 紧接着写v-else二级菜单,因为路由里面还有children也要进行遍历与判断,所以还要用到虚拟标签。
  2. 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>
  1. 这样就利用路由实现了导航的动态渲染。

4. 解决单页应用的一个bug

  1. 不同账号在同一设备登录可能会查看到不属于自己权限的内容。必须要刷新一次。
  2. 因为跳转页面的函数是异步的,所以添加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();
}
posted @   Lyc1cccccccc  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示