课程名称:基于Vue3最新标准,实现后台前端综合解
课程章节: 第一章
课程讲师:Sunday
课程内容
是以 用户-> 角色 -> 权限 的一种关系

登入时 会获取到这些数据
permission 会拿到 菜单定义时 相对应的一个名称

prints 对应的是 用户按钮的权限
role 是一个数组 你有多少角色 就返回多少角色
动态路由

将进行权限控制的路由分别拆开来写 然后将公共的路由单独放在一个json内
export 输出
在src 文件夹下 设置了 permission.js main.js 需要引入
import router from './router'
import store from './store'
// 白名单
const whiteList = ['/login']
/**
* 路由前置守卫
*/
router.beforeEach(async (to, from, next) => {
// 存在 token ,进入主页
// if (store.state.user.token) {
// 快捷访问
if (store.getters.token) {
if (to.path === '/login') {
next('/')
} else {
// 判断用户资料是否获取
// 若不存在用户信息,则需要获取用户信息
if (!store.getters.hasUserInfo) {
// 触发获取用户信息的 action,并获取用户当前权限
const { permission } = await store.dispatch('user/getUserInfo')
// 处理用户权限,筛选出需要添加的权限
const filterRoutes = await store.dispatch(
'permission/filterRoutes',
permission.menus
)
// 利用 addRoute 循环添加
filterRoutes.forEach(item => {
router.addRoute(item)
})
console.log(router)
// 添加完动态路由之后,需要在进行一次主动跳转
return next(to.path)
}
next()
}
} else {
// 没有token的情况下,可以进入白名单
if (whiteList.indexOf(to.path) > -1) {
next()
} else {
next('/login')
}
}
})router.addRoute(item) 是vue-router 4最新提供的动态路由方法
vuex permission.js
// 专门处理权限路由的模块
import { publicRoutes, privateRoutes } from '@/router'
export default {
namespaced: true,
state: {
// 路由表:初始拥有静态路由权限
routes: publicRoutes
},
mutations: {
/**
* 增加路由
*/
setRoutes(state, newRoutes) {
// 永远在静态路由的基础上增加新路由
state.routes = [...publicRoutes, ...newRoutes]
}
},
actions: {
/**
* 根据权限筛选路由
*/
filterRoutes(context, menus) {
const routes = []
// 路由权限匹配
menus.forEach(key => {
// 权限名 与 路由的 name 匹配
routes.push(...privateRoutes.filter(item => item.name === key))
})
// 最后添加 不匹配路由进入 404
routes.push({
path: '/:catchAll(.*)',
redirect: '/404'
})
context.commit('setRoutes', routes)
return routes
}
}
}将 公共的路由和私有的路由 进行整合 判断 filterRoutes(vuex方法,接口获取的menus的permission.name)
用接口获取的name 做循环判断 是否和 路由定义的name相同 如果有则添加进去
在用户退出时 也需要 router.removeRoute(menu)
/**
* 初始化路由表
*/
export function resetRouter() {
if (
store.getters.userInfo &&
store.getters.userInfo.permission &&
store.getters.userInfo.permission.menus
) {
const menus = store.getters.userInfo.permission.menus
menus.forEach((menu) => {
router.removeRoute(menu)
})
}功能受控指令 v-permission="['importUser']"
import store from '@/store'
function checkPermission(el, binding) {
// 获取绑定的值,此处为权限
const { value } = binding
// 获取所有的功能指令
const points = store.getters.userInfo.permission.points
// 当传入的指令集为数组时
if (value && value instanceof Array) {
// 匹配对应的指令
const hasPermission = points.some(point => {
return value.includes(point)
})
// 如果无法匹配,则表示当前用户无该指令,那么删除对应的功能按钮
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
// eslint-disabled-next-line
throw new Error('v-permission value is ["admin","editor"]')
}
}
export default {
// 在绑定元素的父组件被挂载后调用
mounted(el, binding) {
checkPermission(el, binding)
},
// 在包含组件的 VNode 及其子组件的 VNode 更新后调用
update(el, binding) {
checkPermission(el, binding)
}
}自定义了一个 v-permission 设置了内容 判断按钮是否显示
app 也需要引入 app.directive('permission', permission)

随时随地看视频