在Nuxt.js中如何按三类角色区分侧边栏路由菜单元素实例
Nuxt.js 角色权限菜单实现方案
实现步骤
- 给菜单项配置权限标识
在原有的items数组中为每个菜单新增roles字段,标注允许访问的角色,示例中我们定义三类角色:admin(管理员)、expert(专家)、user(普通用户)。 - 新增计算属性过滤菜单
获取当前登录用户的角色(通常登录后会存储在localStorage/sessionStorage或者Vuex状态管理中),通过计算属性动态筛选出当前角色有权限查看的菜单列表。 - 替换模板遍历对象
将模板中v-for遍历的原items数组替换为过滤后的计算属性即可。
完整修改后代码
<template> <v-app dark> <v-navigation-drawer v-model="drawer" :mini-variant="miniVariant" :clipped="clipped" fixed app > <v-list> <Avatar /> <v-list-item v-for="(item, i) in filteredItems" :key="i" :to="item.to" router exact > <v-list-item-action> <v-icon>{{ item.icon }}</v-icon> </v-list-item-action> <v-list-item-content> <v-list-item-title v-text="item.title" /> </v-list-item-content> </v-list-item> </v-list> </v-navigation-drawer> <v-app-bar :clipped-left="clipped" fixed app> <v-app-bar-nav-icon @click.stop="drawer = !drawer" /> <v-btn icon @click.stop="miniVariant = !miniVariant"> <v-icon>mdi-{{ `chevron-${miniVariant ? "right" : "left"}` }}</v-icon> </v-btn> <v-spacer /> <v-toolbar-title class="titulo1" v-text="title" /> </v-app-bar> <!-- 主内容区域 --> <v-main> <v-container> <nuxt /> </v-container> </v-main> <!-- 页脚 --> <v-footer :absolute="!fixed" app> <span>© {{ new Date().getFullYear() }}</span> </v-footer> </v-app> </template> <script> import Avatar from "~/components/Avatar"; export default { data() { return { clipped: true, drawer: false, fixed: false, items: [ { icon: "mdi-apps", title: "登录", to: "/IniciarSesion", roles: ['admin', 'expert', 'user'] }, { icon: "mdi-apps", title: "首页", to: "/", roles: ['admin', 'expert', 'user'] }, { icon: "mdi-apps", title: "查看用户", to: "/_administrador/VerUsuarios", roles: ['admin'] }, { icon: "mdi-apps", title: "正射影像列表", to: "/_especialista/ListarOrtomosaicos", roles: ['expert'] }, { icon: "mdi-apps", title: "上传数据", to: "/_especialista/CargarInformacion", roles: ['expert'] }, { icon: "mdi-apps", title: "数据处理", to: "/_especialista/Procesamiento", roles: ['expert'] }, ], miniVariant: false, right: true, rightDrawer: false, title: "El Potrero", }; }, computed: { currentRole() { // 此处替换为你实际获取当前登录用户角色的逻辑,示例从localStorage取值 return localStorage.getItem('userRole') || 'user' }, filteredItems() { return this.items.filter(item => { // 未配置roles的菜单默认所有角色可访问,可按需调整规则 if (!item.roles) return true return item.roles.includes(this.currentRole) }) } }, components: { Avatar, }, }; </script> <style scoped> .titulo1 { display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; } </style>
安全补充说明
前端仅隐藏菜单属于视觉层面的权限控制,为防止用户手动输入路由地址越权访问,需要额外添加全局路由守卫做权限校验,示例如下:
- 新建
middleware/auth.js文件:
export default function ({ route, redirect }) { const currentRole = localStorage.getItem('userRole') || 'user' // 可在页面的meta字段配置对应允许访问的角色,和菜单权限保持一致 if (route.meta?.roles && !route.meta.roles.includes(currentRole)) { return redirect('/') // 无权限跳转至首页 } }
- 在需要权限校验的页面中添加配置即可,例如管理员页面:
export default { middleware: 'auth', meta: { roles: ['admin'] } // 页面其他逻辑 }
内容的提问来源于stack exchange,提问作者OsvaltOsvalth
相关产品推荐
相关产品推荐

