vue权限管理怎么实现

Z, ZLW 1039

vue权限管理实现思路:1、菜单控制;2、界面控制;3、按钮控制;4、请求和响应控制。后端返回用户权限,前端根据用户权限处理得到左侧菜单;所有路由在前端定义好,根据后端返回的用户权限筛选出需要挂载的路由,然后使用 addRoutes 动态挂载路由。

1、菜单控制:在登录请求当中,会得到权限数据,权限需要在多个组件之间共享,所以可以通过vuex保存数据并且展示相应的菜单,页面刷新的情况下会丢失数据,所以把权限数据存入sessionStorage中。

2、界面控制:如果用户没有登录,手动输入url地址,应该阻止并跳转到登录页面,通过路由导航守卫来实现。动态路由可以让不具备权限的界面在路由规则中不存在

3、按钮控制:路由规则中可以添加元数据meta,通过路由对象可以得到当前的路由规则以及存储在路由规则中的元数据,自定义指令可以实现对按钮的控制

4、请求和响应控制:请求拦截和相应拦截的使用,请求方式约定restful

1、整体思路

后端返回用户权限,前端根据用户权限处理得到左侧菜单;所有路由在前端定义好,根据后端返回的用户权限筛选出需要挂载的路由,然后使用 addRoutes 动态挂载路由。

2、具体实现

a、创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。

b、当用户登录后,获取用role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。

c、调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。

d、使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。

3、代码实现

1、在router.js中定义路由,区分需要权限和不需要权限的路由!

// router.js
import Vue from “vue”;
import VueRouter from “vue-router”;

import Login from ‘../views/login/’;
const dashboard = resolve => require([‘../views/dashboard/index’], resolve);
//使用了vue-routerd的Lazy Loading Routes

//所有权限通用路由表
//如首页和登录页和一些不用权限的公用页面
export const constantRouterMap = [
{ path: ‘/login’, component: Login },
{
path: ‘/’,
component: Layout,
redirect: ‘/dashboard’,
name: ‘首页’,
children: [{ path: ‘dashboard’, component: dashboard }]
},
]

//实例化vue的时候只挂载constantRouter
export default new Router({
routes: constantRouterMap
});

//异步挂载的路由
//动态需要根据权限加载的路由表
export const asyncRouterMap = [
{
path: ‘/permission’,
component: Layout,
name: ‘权限测试’,
meta: { role: [‘admin’,’super_editor’] }, //页面需要的权限
children: [
{
path: ‘index’,
component: Permission,
name: ‘权限测试页’,
meta: { role: [‘admin’,’super_editor’] } //页面需要的权限
}]
},
{ path: ‘*’, redirect: ‘/404’, hidden: true }
];

const createRouter = () => new VueRouter({
// mode: ‘history’, // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})

const router = createRouter()

export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // 重置路由
}
export default router

2、在strore文件中,创建permission.js文件;该文件的作用:通过用户的权限和之前在router.js里面asyncRouterMap的每一个页面所需要的权限做匹配,最后返回一个该用户能够访问路由有哪些 ;

//导入router.js下的静态路由、动态获取的路由映射
import { asyncRoutes, constantRoutes } from ‘@/router’

/**

  • 判断是否有权限
  • @param roles
  • @param route
    */
    function hasPermission(roles, route) {
    if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
    } else {
    return true
    }
    }

/**

  • 过滤出有权限的路由
  • @param routes asyncRoutes
  • @param roles
    */
    export function filterAsyncRoutes(routes, roles) {
    const res = [] routes.forEach(route => {
    const tmp = { …route }
    if (hasPermission(roles, tmp)) {
    if (tmp.children) {
    tmp.children = filterAsyncRoutes(tmp.children, roles)
    }
    res.push(tmp)
    }
    }) return res
    }

const permission = {
state: {
routes: [],
addRoutes: [],
},
getters: {
routes: state => state.routes,
addRoutes: state => state.addRoutes
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)  //把之前的路由和后过滤出来的路由拼接起来一个新数组
},
},
actions: {
// 构建路由的函数
generateRoutes({ commit }, roles) {
return new Promise((resolve) => {
let accessedRoutes
if (roles.includes(“ADMIN”)) {

      accessedRoutes = asyncRoutes || []
    } else {
      accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
    }
    commit("SET_ROUTES", accessedRoutes)
    resolve(accessedRoutes)
  })
},

},
}

export default permission

3、当用户登录后,获取用户role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。

// main.js
router.beforeEach((to, from, next) => {
if (store.getters.token) { // 判断是否有token
if (to.path === ‘/login’) {
next({ path: ‘/’ });
} else {
if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
store.dispatch(‘GetInfo’).then(res => { // 拉取info
const roles = res.data.role;
store.dispatch(‘GenerateRoutes’, { roles }).then(() => { // 生成可访问的路由表
router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
next({ …to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
})
}).catch(err => {
console.log(err);
});
} else {
next() //当有用户权限的时候,说明所有可访问路由已生成 如访问没权限的全面会自动进入404页面
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next();
} else {
next(‘/login’); // 否则全部重定向到登录页
}
}
});

回复

我来回复
  • 暂无回复内容

注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部