前情回顾:

如果对vue路由部分还不是很熟悉的小伙伴,建议可以先去了解一下,或者看一下我的这两篇笔记:

开始~~
在上一章中《 vue-element-admin项目学习笔记(4)路由分析二:动态路由及permission.js》分析了静态路由和动态路由。这一章进行动态路由计算逻辑的分析。

在上一篇中,在项目目录permission.js 中,有这样一段代码:

 // 用获取到的用户信息中的权限,传入VUEX方法,生成路由规则
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)

本篇就展开分析动态路由匹配的详细逻辑

目标文件在:项目目录/src/store/modules/permission.js

// 导入动态、静态路由
import { asyncRoutes, constantRoutes } from '@/router'

// 具体路由规则与用户roles匹配的工具函数,被filterAsyncRoutes调用
// 返回布尔值
function hasPermission(roles, route) {
  // 规则有元信息 且 元信息 有roles项
  if (route.meta && route.meta.roles) {
    // 开始比对,role在不在route.meta.roles中,返回比对结果
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    //没有元信息,可以返回真,说明没有配置权限,可以访问
    return true
  }
}

// 遍历路由规则与用户roles匹配的工具函数
export function filterAsyncRoutes(routes, roles) {
  const res = []
  // 遍历传过来的所有动态路由规则进行遍历
  routes.forEach(route => {
    // tmp 每一个规则
    const tmp = { ...route }
    // 调用hasPermission方法(布尔值),进行匹配
    if (hasPermission(roles, tmp)) {
      // 子级路由递归计算
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

// 两个状态、数组routes、addRoutes
// routes 当前用户所有路由
// addRoutes 当前用户动态路由。权限计算出来的
// 通过浏览器vue插件可以观察看到
const state = {
  routes: [],
  addRoutes: []
}

// mutations操作state
// 给这两个数组赋值
const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}
// actions操作异步
// generateRoutes方法,计算生成权限动态路由
const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      // 定义一个临时变量
      let accessedRoutes
      // 当前用户的roles中是否包含admin
      if (roles.includes('admin')) {
        // 包含的话,就把所有动态路由规则给它,asyncRoutes是所有动态路由,导入的
        // admin用户不用计算
        accessedRoutes = asyncRoutes || []
      } else {
        //  否则在所有动态路由规则中进行过滤匹配
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      // 提交修改数组
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

06-14 04:26