vue-admin-better前端页面-菜单-权限配置
Posted 捡黄金的少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue-admin-better前端页面-菜单-权限配置相关的知识,希望对你有一定的参考价值。
码云地址:
https://gitee.com/chu1204505056/vue-admin-better
其登录逻辑为:
1、登录拿取到token,分配到vuex中;
2、通过token拿取到用户的permission角色名称,用户头像,昵称,并存放到vuex中;
3、每次路由时候,调取配置的permission.js ,如果没有角色名称,则返回第二步,如果有,则通
过token向后台请求当前用户的权限路由,并对基础路由进行拼接,存放到vuex中进行状态管理;
1、登录部分
调用 this.$store .dispatch('user/login', this.form)并返回值,
user/login这样调用是因为,store中导出namespaced为true,就可以根据简写找到vuex中actions的方法
export default
namespaced: true,//引用需要的模块名称 /menu/GetUserMenu
state,
mutations,
actions
login()
this.loading = true
this.$store
.dispatch('user/login', this.form)
.then(() =>
const routerPath = '/'
this.$router.push(routerPath).catch(() => )
this.loading = false
)
.catch(() =>
this.loading = false
)
,
import getUserInfo, login, logout from '@/api/userRegistration'
调用自己定义的登录接口,主要返回token
async login( commit , userInfo)
const data = await login(userInfo)
const accessToken = data.access_token;
const setUserInfo=data.userInfo
if (accessToken)
commit('setAccessToken', accessToken)
commit('setUserInfo',setUserInfo)
const hour = new Date().getHours()
console.log(hour)
const thisTime =
hour < 8
? '早上好'
: hour <= 11
? '上午好'
: hour <= 13
? '中午好'
: hour < 18
? '下午好'
: '晚上好'
Vue.prototype.$baseNotify(`欢迎登录$title`, `$thisTime!`)
else
Vue.prototype.$baseMessage(
`登录接口异常,未正确返回$tokenName...`,
'error'
)
,
登录接口
我后台采用 Spring Scurity的oauth2进行登录,接口如下
// 数据格式
const headers = 'Content-Type': 'application/x-www-form-urlencoded'
// 请求头添加 Authorization: Basic client_id:client_secret
const auth =
username: 'mxg-blog-admin',
password: '123456',
export function login(data)
return request(
headers: headers,
auth: auth,
url: `/supplierAuth/login`,
method: 'POST',
params: data,
)
返回字段如下
2、permission.js 进行路由拦截
采用如下,对每次路由进行拦截
router.beforeResolve(async (to, from, next) =>
逻辑还是比较好理解
1、判断是否有token,判断路由是否在白名单
2、判断是否有权限角色(user/permissions)存储
3、如果没有则获取用户权限,获取路由并拼接,如果存在,则直接访问
router.beforeResolve(async (to, from, next) =>
if (progressBar) VabProgress.start()
let hasToken = store.getters['user/accessToken']
if (hasToken)
if (to.path === '/login')
next( path: '/' )
if (progressBar) VabProgress.done()
else
const hasPermissions =
store.getters['user/permissions'] &&
store.getters['user/permissions'].length > 0
if (hasPermissions)
next()
else
try
let permissions
if (!loginInterception)
//settings.js loginInterception为false时,创建虚拟权限
await store.dispatch('user/setPermissions', ['admin'])
permissions = ['admin']
else
permissions = await store.dispatch('user/getUserInfo')
let accessRoutes = []
if (authentication === 'intelligence')
accessRoutes = await store.dispatch('routes/setRoutes', permissions)
else if (authentication === 'all')
// console.log("all")
console.log('拿取到用户信息')
accessRoutes = await store.dispatch('routes/setAllRoutes')
console.log(accessRoutes)
accessRoutes.forEach((item) =>
console.log(item)
router.addRoute(item)
)
next( ...to, replace: true )
catch
await store.dispatch('user/resetAccessToken')
if (progressBar) VabProgress.done()
else
console.log(routesWhiteList)
if (routesWhiteList.indexOf(to.path) !== -1)
next()
else
if (recordRoute)
next(`/login?redirect=$to.path`)
else
next('/login')
if (progressBar) VabProgress.done()
document.title = getPageTitle(to.meta.title)
)
router.afterEach(() =>
if (progressBar) VabProgress.done()
)
获取用户信息
permissions = await store.dispatch('user/getUserInfo')
获取用户信息
async getUserInfo( commit, state )
const data = await getUserInfo(state.accessToken)
if (!data)
Vue.prototype.$baseMessage('验证失败,请重新登录...', 'error')
return false
let permissions, username, avatar = data
if (permissions && username && Array.isArray(permissions))
commit('setPermissions', permissions)
commit('setUsername', username)
commit('setAvatar', avatar)
return permissions
else
Vue.prototype.$baseMessage('用户信息接口异常', 'error')
return false
,
接口如下 ,这个后台可以根据token,自由发挥
export function getUserInfo(accessToken)
return request(
url: '/supplierSystem/menu/userPermission',
method: 'post',
data:
"accessToken": accessToken,
,
)
获取在permission.js中路由,并动态添加到route中
accessRoutes = await store.dispatch('routes/setAllRoutes')
console.log(accessRoutes)
accessRoutes.forEach((item) =>
console.log(item)
router.addRoute(item)
)
在store中找到routes/setAllRoutes方法,获取后台当前用户路由,这个路由,后台要按照前端方式拼接
这个是源代码的设置路由
async setAllRoutes( commit )
let data = await getRouterList()
data.push( path: '*', redirect: '/404', hidden: true )
let accessRoutes = convertRouter(data)
console.log(accessRoutes);
commit('setAllRoutes', accessRoutes)
return accessRoutes
,
这个是我的设置的路由。主要是加入了按钮的权限集合在里面
async setAllRoutes( commit )
let data = await getRouterList()
let dataRoute = data.menuTreeList
dataRoute.push( path: '*', redirect: '/404', hidden: true )
let accessRoutes = convertRouter(dataRoute)
commit('setAllRoutes', accessRoutes)
commit('setButtonList', data.buttonList)
return accessRoutes
,
const state = () => (
routes: [],
partialRoutes: [],
buttonList: [],
)
const getters =
routes: (state) => state.routes,
partialRoutes: (state) => state.partialRoutes,
buttonList: (state) => state.buttonList,
const mutations =
setRoutes(state, routes)
state.routes = constantRoutes.concat(routes)
,
setAllRoutes(state, routes)
state.routes = constantRoutes.concat(routes)
,
setButtonList(state, buttonList)
state.buttonList = buttonList
,
setPartialRoutes(state, routes)
state.partialRoutes = constantRoutes.concat(routes)
,
后端构建的菜单结构模式如下
path: '/',
component: 'Layout',
redirect: 'index',
children: [
path: 'index',
name: 'Index',
component: '@/views/index/index',
meta:
title: '首页',
icon: 'home',
affix: true,
,
,
],
,
path: '/personnelManagement',
component: 'Layout',
redirect: 'noRedirect',
name: 'PersonnelManagement',
meta: title: '人员', icon: 'users-cog', permissions: ['admin'] ,
children: [
path: 'userManagement',
name: 'UserManagement',
component: '@/views/personnelManagement/userManagement/index',
meta: title: '用户管理' ,
,
path: 'roleManagement',
name: 'RoleManagement',
component: '@/views/personnelManagement/roleManagement/index',
meta: title: '角色管理' ,
,
path: 'menuManagement',
name: 'MenuManagement',
component: '@/views/personnelManagement/menuManagement/index',
meta: title: '菜单管理', badge: 'New' ,
,
],
,
后端测试构建菜单 (没有加按钮权限集合)
@Override
public Result selectMenuThreeByUserIdTwo(String userId)
ArrayList<Object> arrayList = new ArrayList<>();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("path", "/");
hashMap.put("component", "Layout");
hashMap.put("redirect", "index");
LinkedList<Object> children = new LinkedList<>();
HashMap<String, Object> hashMap1 = new HashMap<>();
hashMap1.put("path", "index");
hashMap1.put("name", "Index");
hashMap1.put("component", "@/views/index/index");
HashMap<Object, Object> hashMap2 = new HashMap<>();
hashMap2.put("title", "首页");
hashMap1.put("meta", hashMap2);
children.add(hashMap1);
hashMap.put("children", children);
arrayList.add(hashMap);
HashMap<String, Object> hashMap11 = new HashMap<>();
hashMap11.put("path", "/personnelManagement");
hashMap11.put("component", "Layout");
hashMap11.put("redirect", "noRedirect");
hashMap11.put("name", "PersonnelManagement");
HashMap<Object, Object> hashMap22 = new HashMap<>();
hashMap22.put("title", "人员管理");
hashMap11.put("meta", hashMap22);
ArrayList<Object> arrayList2 = new ArrayList<>();
HashMap<Object, Object> hashMap3 = new HashMap<>();
hashMap3.put("path", "userManagement");
hashMap3.put("name", "UserManagement");
hashMap3.put("component", "@/views/personnelManagement/userManagement/index");
HashMap<Object, Object> hashMap4 = new HashMap<>();
hashMap4.put("title", "人员管理");
hashMap3.put("meta", hashMap4);
arrayList2.add(hashMap3);
HashMap<Object, Object> hashMap5 = new HashMap<>();
hashMap5.put("path", "roleManagement");
hashMap5.put("name", "roleManagement");
hashMap5.put("component", "@/views/personnelManagement/roleManagement/index");
HashMap<Object, Object> hashMap6 = new HashMap<>();
hashMap6.put("title", "角色管理");
hashMap5.put("meta", hashMap6);
arrayList2.add(hashMap5);
HashMap<Object, Object> hashMap7 = new HashMap<>();
hashMap7.put("path", "roleManagement");
hashMap7.put("name", "roleManagement");
hashMap7.put("component", "@/views/personnelManagement/roleManagement/index");
HashMap<Object, Object> hashMap8 = new HashMap<>();
hashMap8.put("title", "菜单管理");
// hashMap8.put("badge","New");
hashMap7.put("meta", hashMap6);
arrayList2.add(hashMap7);
hashMap11.put("children", arrayList2);
arrayList.add(hashMap11);
return Result.ok(arrayList);
右边页面
通过如下导入的 vab-side-bar文件,如果你想自定义修改菜单栏,则可以找到下面修改
在nodemudle中可以查看下载的菜单文件,
3、自定义按钮权限
前面在菜单和按钮集合存在vuex之后;配置自定义指令,来显示或者隐藏按钮
// 引入所有要注册的全局指令
import permission from './permission'
// 将permission文件导出的对象引入
export default (Vue) =>
// 第一个参数为指令名称,v-permission 使用,
// 注意在生命指令名时候,不能加v-
Vue.directive('permission', permission)
// 然后在main.js 中全局引入这个文件
permission .js如下
//自定义权限指令
import store from '@/store/index'
// 导出一个对象
export default
// 指令钩子
inserted(el, binding)
//el 指令作用到哪个元素上
//获取使用指令时传递的值
const value = binding
//获取用户当前所拥有的按钮权限
// store.getters['user/permissions']
// const buttonList = store.getters && store.getters.buttonList
const buttonList = store.getters['routes/buttonList']
if (value)
// 用some,不用foreach 因为如果下面为true,则进行终止循环
const hasPermission = buttonList.some((button) =>
return button === value
)
// 如果没有权限,则将元素移除
if (!hasPermission)
el.parentNode && el.parentNode.removeChild(el)
else
throw new Error("需要权限标识!比如v-permission='article:delete'")
,
在main.js中引入这个自定义指令,
import directive from '@/directive' //导入自定义指令
Vue.use(directive)
使用如下
<el-button
type="primary"
@click="handleQuery"
v-permission="'user:search'"
>
搜索
</el-button>
以上是关于vue-admin-better前端页面-菜单-权限配置的主要内容,如果未能解决你的问题,请参考以下文章