vue router权限管理实现不同角色显示不同路由
短信预约 -IT技能 免费直播动态提醒
思路:
- 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 class="lazy" data-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"
class="lazy" data-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 不同角色显示不同路由内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341