vue router权限管理实现不同角色显示不同路由
时间:2022-07-13 08:26:58|栏目:vue|点击: 次
思路:
- 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实现文章点赞和差评功能
栏 目:vue
本文标题:vue router权限管理实现不同角色显示不同路由
本文地址:http://www.codeinn.net/misctech/207625.html