vue-admin-template学习

vue-admin-template 权限篇

  • 参考网址
- https://juejin.cn/post/6844903478880370701
- https://blog.csdn.net/qq_36050563/article/details/112990775
  • 思路:
- 不同权限对应不同的路由
- 侧边栏也需要根据不同的权限,异步生成
  • 实现逻辑
- 用户名和密码校验是否正确
	- 正确返回token,存储到cookie(记住用户登录状态)
	- 带着token向后端发请求,获取用户信息userInfo
		- userInfo包含'用户权限'信息
		- 即通过token获取到role,再根据role算出其对应有权限的路由
		  最后通过router.addRoutes动态挂载这些路由
		 
- 上述所有的数据和操作都是通过vuex全局管理控制的(补充说明:刷新页面后 vuex的内容也会丢失,所以需要重复上述的那些操作)
  • 具体实现
- 创建vue实例的时候挂载vue-router(挂载一些不用权限的公用的页面,比如登录页,后台首页)
- 当用户登录后,通过请求userInfo获取role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表
- 调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由
- 使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件
  • 代码实现
// router.js

import Vue from 'vue';
import Router from 'vue-router';

import Login from '../views/login/';
const dashboard = resolve => require(['../views/dashboard/index'], resolve);
//使用了vue-routerd的[Lazy Loading Routes
](https://router.vuejs.org/en/advanced/lazy-loading.html)

//所有权限通用路由表 
//如首页和登录页和一些不用权限的公用页面
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 }
];

- 注意事项: meta标签,用来标识有哪些权限可以访问该页面,如meta: { role: ['admin','super_editor'] }表示该页面只有admin和超级编辑才能有资格进入
	- 因此,只要获取到后端的role列表,对比一下,该用户的权限就出来了,再匹配一下路由,从而生成最终的权限范围页面

  • 发请求获取后端数据permissions
// permission.js


/*
- 后端permisson数据
	data': {'id': 3, ......,'permissions': ['monitor-error', 'monitor-ip-update', 'monitor-ip-add', 'monitor-users-lock', 'monitor-service', 'system', 'monitor-users', 'system-departments-get', 'monitor-error-clear', 'monitor-users-black-ip', 'system-departments', 'monitor-ip-del', 'monitor-ip', 'monitor-ip-mdel', 'monitor']}
*/

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(() => { // 派发action,生成可访问的路由表
            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'); // 否则全部重定向到登录页
    }
  }
});

  • 详解派发action,生成可访问的路由表
// store/permission.js
import { asyncRouterMap, constantRouterMap } from 'src/router';

function hasPermission(roles, route) {
  if (route.meta && route.meta.role) {
    return roles.some(role => route.meta.role.indexOf(role) >= 0)
  } else {
    return true
  }
}

const permission = {
  state: {
    routers: constantRouterMap,
    addRouters: []
  },
  mutations: {
    SET_ROUTERS: (state, routers) => {
      state.addRouters = routers;
      state.routers = constantRouterMap.concat(routers);
    }
  },
  actions: {
    GenerateRoutes({ commit }, data) {
      return new Promise(resolve => {
        const { roles } = data;
        const accessedRouters = asyncRouterMap.filter(v => {
          if (roles.indexOf('admin') >= 0) return true;
          if (hasPermission(roles, v)) {
            if (v.children && v.children.length > 0) {
              v.children = v.children.filter(child => {
                if (hasPermission(roles, child)) {
                  return child
                }
                return false;
              });
              return v
            } else {
              return v
            }
          }
          return false;
        });
        commit('SET_ROUTERS', accessedRouters);
        resolve();
      })
    }
  }
};

export default permission;

/*
通过用户的权限和之前在router.js里面asyncRouterMap的每一个页面所需要的权限做匹配,最后返回一个该用户能够访问路由有哪些
*/
- main.js 引入 router.js 和 permission.js
  • x渲染侧边栏
posted @ 2024-11-27 16:19  清安宁  阅读(43)  评论(0编辑  收藏  举报