vue router权限管理实现不同角色显示不同路由
更新时间:2022年03月07日 08:35:00 作者:嘿,小苹果
本文主要介绍了vue router权限管理实现不同角色显示不同路由,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
思路:
- login页面登录时 加上角色的标记,存储到本地缓存(localstorage)
- 路由js文件,meta属性加个是否可见(visiable true或false)
- home 基本导航栏页面逻辑,首先 可以获得到 所有一级菜单和角色标记
- for 循环一级菜单
- 找出角色 所在的 角色数组(判断某个值在不在 数组中)
- 然后 所在的数组 visiable 改为true ,其他的改为false
ui框架 是ant design of vue
主要逻辑代码
1-登录页面
2- 路由页面
3- home 菜单栏公用页面
全部页面代码
1. 登录页面
<template> <div class='container'> <div class="bg-image"> <p @click="demo">登录</p> </div> </div> </template> <script> export default { name: "", data() { return { role:'user' }; }, methods: { demo(){ if (this.role === 'superadmin') { window.localStorage.setItem('roles','superadmin') } else if (this.role === 'admin') { window.localStorage.setItem('roles','admin') } else if (this.role === 'user') { window.localStorage.setItem('roles','user') } } }, }; </script> <style scoped> </style>
2. 路由js文件
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' Vue.use(Router) export default new Router({ routes: [ //一级路由 { path: "/login", name: "Login", meta: { requireAuth: false }, component: require("@/view/Login").default, }, // 提供页面框架 { path: "/", name: "Home", meta: { requireAuth: true }, component: require("@/view/Home").default, redirect: "/index", children:[ { path: '/HelloWorld', name: 'HelloWorld', component: HelloWorld, meta: {requireAuth: false, visiable: true,roles: ['superadmin','admin','user']} }, { path: '/SuperAdmin', name: 'SuperAdmin', component: () => import("@/view/SuperAdmin.vue"), meta: {requireAuth: false, visiable: true, roles: ['superadmin']} }, { path: '/Admin', name: 'Admin', component: () => import("@/view/Admin.vue"), meta: {requireAuth: false, visiable: true, roles: ['admin']} }, { path: '/User', name: 'User', component: () => import("@/view/User.vue"), meta: {requireAuth: false, visiable: true,roles: ['user']} }, ], } ] })
3. home公用菜单栏页面(ui框架 是ant design of vue)
<template> <a-layout id="components-layout-demo-custom-trigger"> <a-layout-sider v-model="collapsed" :trigger="null" collapsible> <div class="logo"> <span class="anticon"> <!-- <img src="../assets/image/logo.png" alt="" /> --> </span> <p v-if="!collapsed">项目名</p> </div> <a-menu theme="dark" mode="inline" :defaultSelectedKeys="[current]" :selectedKeys="[current]" @click="handleClick" @openChange="onOpenChange" :open-keys="openKeys" > <template v-for="item in menuList"> <!-- 有一级以上 --> <a-sub-menu :key="item.path" v-if="item.children != undefined && item.meta.visiable" > <p slot="title"> <span class="anticon"> <a-icon :type="item.meta.icon" /> </span> <span>{{ item.name }} </span> </p> <!-- 二级页面 --> <template v-for="child in item.children"> <a-menu-item :key="child.path" v-if="child.meta.visiable"> <p class="ciclebox"> <span> {{ child.name }}</span> </p> </a-menu-item> </template> </a-sub-menu> <!-- 普通只有一级的页面 --> <a-menu-item :key="item.path" v-if="item.children == undefined && item.meta.visiable" > <a-icon :type="item.meta.icon" /> <span>{{ item.name }}</span> </a-menu-item> </template> </a-menu> </a-layout-sider> <a-layout :style="'width:' + (fullWidth - 200) + 'px'"> <a-layout-header style="background: #fff; padding: 0; height: 60px"> <div class="headerflex"> <a-icon class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="() => (collapsed = !collapsed)" /> <div class="app-header-right"> <a-menu mode="horizontal" @click="handleClickLogin"> <a-sub-menu> <span class="app-user-avatar" slot="title"> <a-avatar size="small" src="https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png" /> <!-- 用户名 --> <!-- {{ User ? User.username : "" }} --> <a-icon type="down" class="icon" /> </span> <!-- <a-menu-item key="/setting/password" ><a-icon type="lock" key="password" />修改密码 </a-menu-item> --> <a-menu-item key="/login" ><a-icon type="poweroff" />退出登录 </a-menu-item> </a-sub-menu> </a-menu> </div> </div> </a-layout-header> <a-layout-content style="padding-top: 4px"> <!-- 这里显示页面内容 --> <router-view></router-view> </a-layout-content> </a-layout> </a-layout> </template> <script> import routes from "../router"; export default { name: "Home", components: {}, data() { return { collapsed: false, menuList: [], //菜单循环列表 subList: [], // 二级子菜单 type: "", // 请求参数type类型 typeshow: false, // false 没提醒 true 有提醒 current: this.$route.path, openKeys: [], rootSubmenuKeys: [], flag: false, fullWidth: document.documentElement.clientWidth, // 消息提醒 num: "", // 回收员审核 ordernum: "", // 订单列表 cycleordernum: "", // 周期回收列表 promoterverify: "", // 推广审核 userwithdraw: "", // 会员提现审核 recyclewithdraw: "", // 回收员提现审核 promotionwithdraw: "", // 推广员提现审核 roles:'', // 角色显示 }; }, created() { let that = this; this.menuList = routes.options.routes[1].children; console.log(this.menuList, "一级菜单"); this.rootSubmenuKeys = this.menuList; this.roles = window.localStorage.getItem('roles'); this.menuList.forEach(element => { // 1- for 循环一级菜单 // 2-找出角色 所在的 角色数组(判断某个值在不在 数组中) // 3- 然后 所在的数组 visiable 改为true ,其他的改为false element.meta.roles.forEach(item => { if( item.includes(that.roles)){ // 存在 element.meta.visiable = true } else { // 不存在 element.meta.visiable = false } }); }); }, mounted() { //监听屏幕宽度 const that = this; window.onresize = () => { return (() => { window.fullWidth = document.documentElement.clientWidth; that.fullWidth = window.fullWidth; })(); }; }, methods: { onOpenChange(openKeys) { // 最新的key值 const latestOpenKey = openKeys.find( (key) => this.openKeys.indexOf(key) === -1 ); if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) { this.openKeys = openKeys; } else { this.openKeys = latestOpenKey ? [latestOpenKey] : []; } }, handleClick(e) { //如果key为路由则跳转 this.current = e.key; if (e.key.indexOf("/") > -1) { this.$router.push(e.key).catch(() => {}); } }, // 退出登录 handleClickLogin(e) { this.current = e.key; this.openCurrent = e.key; if (e.key == "/login") { localStorage.clear(); setTimeout(() => { this.$router.replace({ path: "/logout", name: "Login" }); }, 300); } }, }, }; </script> <style> /* 退出登录 */ .headerflex { display: flex; align-items: center; justify-content: space-between; } .rights { padding: 0 24px; } #components-layout-demo-custom-trigger .trigger { font-size: 18px; height: 60px !important; line-height: 60px !important; padding: 0 24px; cursor: pointer; transition: color 0.3s; } #components-layout-demo-custom-trigger .trigger:hover { color: #1890ff; } #components-layout-demo-custom-trigger .logo { height: 52px; margin: 16px 16px 10px; display: flex; align-items: center; } #components-layout-demo-custom-trigger .logo img { width: 30px; height: 30px; margin-right: 10px; } #components-layout-demo-custom-trigger .logo p { color: #fff; margin-bottom: 0; font-size: 16px; font-weight: 700; } .ciclebox { position: relative; } .ciclered { position: absolute; right: 0; top: 50%; transform: translateY(-50%); display: inline-block; width: 15px; height: 15px; border-radius: 50%; text-align: center; line-height: 15px; background-color: #e72c0b; color: #fff; font-size: 12px; } .icon { padding-left: 10px; } .app-header-right .ant-menu-horizontal { line-height: 60px !important; } .app-user-avatar img{ width:20px; height:20px; } * p { margin-bottom: 0 !important; } * ul, * li { padding: 0; margin: 0; list-style: none; } .ant-card-body { padding-top: 20px; } .change-inline { display: inline-block; } .container .page-header { height: 84px; padding: 16px; background-color: #fff; } .container .page-header h3 { font-size: 20px; padding-top: 8px; font-weight: 600; } .container .claear-top-height { height: auto !important; } .container .infomation-box-top { margin-top: 10px; } .container .infomation-box-top h3 { font-weight: 600; margin-bottom: 14px; } .container .infomation-box-top p { margin-bottom: 0; line-height: 38px; color: #4b4b4b; } .container .infomation-box-top .status-identity { height: 108px; display: flex; align-items: flex-end; justify-content: center; } .container .infomation-box-top .status-identity .type-title { color: #666666; font-weight: 600; } .container .infomation-box-top .status-identity p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .container .infomation-box-top .status-identity .set-width { width: 80%; } .container .infomation-box-top .status-identity .set-width .add-right-border { height: 76px; border-right: 2px solid #F4F4F4; } .container .infomation-box-top .status-identity .set-width .add-right-border span { font-weight: 600; } .container .infomation-box-top .status-identity .set-width .add-right-border .money-edit { display: flex; align-items: center; justify-content: space-between; } .container .infomation-box-top .status-identity .set-width .add-right-border .anticon { margin-right: 10% !important; } .container .infomation-box-top .status-identity .set-width .add-right-border .edit-icon-color { color: #2B85E4; } .container .set-flex-end { display: flex; justify-content: flex-end; margin-bottom: 16px; } .container .set-flex-end .button-group { display: flex; align-items: center; } .container .set-flex-end .button-group .search { margin-right: 16px; } .container .table-style .recommender { text-decoration: underline; color: #2B85E4; } .container .table-style .table-role { margin-bottom: 0; cursor: default; } .container .table-style .role-r { color: #19BE6B; } .container .table-style .role-s { color: #FF9900; } .container .table-style .role-t { color: #2B85E4; } .container .table-style .role-w { color: #F56C6C; } .container .table-style .role-c { color: #8b8b8b; } .container .table-style .text-detail { color: #409EFF; padding: auto 10px !important; } .container .table-style .addleft-padding { padding-left: 10px; } .container .table-style .order-to { color: #409EFF; padding-left: 10px !important; } .container .table-style .text-stop { color: #F56C6C; padding-left: 10px !important; } .container .table-style .text-stopis { color: #2fc25b; padding-left: 10px !important; } .container .pagination-margin { margin-top: 25px; display: flex; justify-content: flex-end; } .container .ant-tabs-bar { padding-left: 30px; background: #fff; font-weight: 600; margin: 0 0 26px !important; } .container .ant-tabs-nav { font-size: 15px !important; } .container .ant-tabs-nav .ant-tabs-tab { margin-right: 0 !important; padding-bottom: 20px; } .container .tab-pane-set { padding: 0 2%; } .container .ant-card-head-title { padding: 0px; min-height: 44px !important; line-height: 44px; font-size: 15px; font-weight: 600; color: #6b6b6b; } .padbox { margin-left: 10px; } .appoint { background: #e72c0b; color: #e72c0b !important; } .wait { background: #ff9900; color: #ff9900 !important; } .pass { background: #2fc25b; color: #2fc25b; } .success { background: #409eff; color: #409eff !important; } .cancel { background: #8b8b8b; color: #8b8b8b; } .red { color: #e72c0b !important; } .appoint_cl { color: #e72c0b !important; } .wait_cl { color: #ff9900 !important; } .pass_cl { color: #2fc25b !important; } .success_cl { color: #409eff !important; } .cancel_cl { color: #8b8b8b !important; } .clear-bg { background: none !important; } </style>
项目目录
到此这篇关于vue router权限管理实现不同角色显示不同路由的文章就介绍到这了,更多相关vue router 不同角色显示不同路由内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Vue中@click.stop与@click.prevent、@click.native使用
这篇文章主要介绍了Vue中@click.stop与@click.prevent、@click.native使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-08-08详解Vue.js使用Swiper.js在iOS<11时出现错误
这篇文章主要介绍了详解Vue.js使用Swiper.js在iOS<11时出现错误,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-09-09
最新评论