目录权限路由权限store存储路由router添加路由菜单权限按钮权限准备:存储按钮标识指令函数权限 路由权限 静态路由:固定的路由,没有权限。如login页面动态路由:根据不同的角
//地址:store/modules/permission
import { routes as constantRoutes } from '@/router'
// 根据meta.roles去判断该角色是否有路由权限
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return route.meta.roles.some(val => val === roles)
}
return true
}
export function filterAsyncRoutes(routes, roles) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (hasPermission(roles, tmp)) {
if (tmp.children) {
//后台传来的路由字符串,转换为组件对象
// let a = `../views/${route.component}`;
// route.component = () => import(a); // 导入组件
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
//模拟后端传过来的路由
export const asyncRoutes = [
{
path: '/',
name: 'home',
redirect: '/PickupTask',
meta: {
title: '首页',
//纯前端去做动态路由
roles: ['admin']
},
component: () => import('@/views/HomeView.Vue'),
children: [
{
path: 'PickupTask',
name: 'PickupTask',
meta: {
title: 'PickupTask',
},
component: () => import('@/views/Sd/PickupTask.vue'),
},
{
path: 'access',
hidden: true,
component: () => import('@/views/demo/Access.vue'),
meta: {
title: 'access',
roles: ['admin'],
//按钮权限标识
button: {
'btn:access:createUser': 'hidden',
'btn:access:editUser': 'disable'
},
},
},
],
}
]
const permisssion = {
// namespaced: true, -> store.dispatch('permisssion/generateRoutes', 'admin');
state: {
//静态路由+动态路由
routes: [],
//动态路由
addRoutes: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
},
actions: {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
}
export default permisssion
将store中的动态路由使用addRoute添加(最新版本去掉了addRoutes只能使用addRoute添加路由)。
//地址:router/index
import Vue from 'vue';
import VueRouter, { RouteConfig } from 'vue-router';
import store from '@/store';
Vue.use(VueRouter);
const isProd = process.env.node_ENV === 'production';
const routerContext = require.context('./', true, /index.js$/);
//静态路由
export let routes: any = [];
routerContext.keys().forEach((route) => {
// route就是路径
// 如果是根目录的index不做处理
if (route.startsWith('./index')) {
return;
}
const routerModule = routerContext(route);
routes = [...routes, ...(routerModule.default || routerModule)];
});
// 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
mode: 'history',
base: isProd ? '/vue-demo/' : process.env.BASE_URL,
routes,
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash,
};
}
},
});
let reGISterRouteFresh = true;
router.beforeEach(async (to: any, from, next) => {
//设置当前页的title
document.title = to.meta.title;
if (to.path === '/login' && localStorage.getItem('token')) {
next('/');
}
console.log(registerRouteFresh);
//如果首次或者刷新界面,next(...to, replace: true)会循环遍历路由,
//如果to找不到对应的路由那么他会再执行一次beforeEach((to, from, next))直到找到对应的路由,
//我们的问题在于页面刷新以后异步获取数据,直接执行next()感觉路由添加了但是在next()之后执行的,
//所以我们没法导航到相应的界面。这里使用变量registerRouteFresh变量做记录,直到找到相应的路由以后,把值设置为false然后走else执行next(),整个流程就走完了,路由也就添加完了。
if (registerRouteFresh) {
//设置路由
const accessRoutes = await store.dispatch('generateRoutes', 'admin');
let errorPage = {
path: '*',
name: '404',
component: () => import('../views/404.vue'),
};
// 将404添加进去
// 现在才添加的原因是:作为一级路由,当刷新,动态路由还未加载,路由就已经做了匹配,找不到就跳到了404
router.addRoute({ ...errorPage });
accessRoutes.forEach((item: RouteConfig) => {
router.addRoute(item);
});
//获取路由配置
console.log(router.getRoutes());
//通过next({...to, replace})解决刷新后路由失效的问题
next({ ...to, replace: true });
registerRouteFresh = false;
} else {
next();
}
next();
});
export default router;
路由遍历,通过store路由权限中的permission.state.routes去做处理
//地址:store/modules/user
import {
userInfo,
} from '@/api'
const user = {
state: {
role: 'admin',
mockButton: {
'btn:access:createUser': 'show',
'btn:access:editUser': 'show'
}
},
//更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
mutations: {
change_role: (state, data) => {
state.role = data.role
},
change_btn: (state, data) => {
state.mockButton = data.mockButton
}
},
}
export default user
通过模拟传入按钮标识的属性,去判断按钮是否隐藏或者禁用
//地址:directive/permission/index
import permission from './permissionBtn'
const install = function(Vue) {
Vue.directive('permission', permission)
}
if (window.Vue) {
window['permission'] = permission
Vue.use(install); // eslint-disable-line
}
permission.install = install
export default permission
//地址:directive/permission/permissionBtn
import store from '@/store'
function checkPermission(el, binding) {
const { value } = binding
const roles = store.getters && store.getters.role
// 获取模拟权限按钮标识
const mockButton = store.getters && store.getters.mockButton
// 设置按钮属性
if (mockButton[value] === 'disabled') {
el.disabled = true
el.setAttribute('disabled', true)
}
if (mockButton[value] === 'hidden') {
el.style.display = 'none'
}
if (mockButton[value] === 'show') {
el.style.display = 'block'
el.disabled = false
}
// throw new Error(`need roles! Like v-permission="['admin','editor']"`)
}
export default {
inserted(el, binding) {
checkPermission(el, binding)
},
update(el, binding) {
checkPermission(el, binding)
}
}
//应用
<template>
<div>
<a-button @click="changeRole">切换角色</a-button>
<span>当前角色:{{ role }}</span>
<!-- 注意一定要加disabled属性,才能设置它的disabled值 -->
<a-button :disabled="false" v-permission="'btn:access:createUser'">
新建用户
</a-button>
<a-button :disabled="false" v-permission="'btn:access:editUser'">
编辑用户
</a-button>
</div>
</template>
<script lang='ts'>
import { Vue, Component, Watch } from "vue-property-decorator";
import permission from "@/directive/permission/index.js"; // 权限判断指令
// import checkPermission from '@/utils/permission' // 权限判断函数
@Component({
directives: {
permission,
},
computed: {
role() {
return this.$store.getters.role;
},
},
})
export default class Access extends Vue {
get role() {
return this.$store.getters.role;
}
changeRole() {
//设置按钮权限
this.$store.commit("change_btn", {
mockButton:
this.role === "admin"
? {
"btn:access:createUser": "hidden",
"btn:access:editUser": "disabled",
}
: {
"btn:access:createUser": "show",
"btn:access:editUser": "show",
},
});
//设置角色
this.$store.commit("change_role", {
role: this.role === "admin" ? "edit" : "admin",
});
}
}
</script>
export default function checkPermission(value) {
if (value && value instanceof Array && value.length > 0) {
const roles = store.getters && store.getters.roles
const permissionRoles = value
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
return hasPermission
}
console.error(`need roles! Like v-permission="['admin','editor']"`)
return false
}
<template>
<div>
<a-button
v-if="hasPerms('btn:access:createUser')"
:disable="hasPerms('btn:access:createUser')"
>
新建用户
</a-button>
<a-button
v-if="hasPerms('btn:access:editUser')"
:disable="hasPerms('btn:access:editUser')"
>
编辑用户
</a-button>
</div>
</template>
<script lang='ts'>
import { Vue, Component, Watch } from "vue-property-decorator";
import checkPermission from "@/utils/permission"; // 权限判断函数
@Component
export default class Access extends Vue {
hasPerms(params) {
return checkPermission(params);
}
}
</script>
到此这篇关于vue2模拟vue-element-admin手写角色权限的实现的文章就介绍到这了,更多相关vue2 角色权限内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: vue2模拟vue-element-admin手写角色权限的实现
本文链接: https://lsjlt.com/news/154290.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0