如何从零开始设计一套权限&路由鉴权体系?【系列二】

497 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

往期回顾

如何从零开始设计一套权限&路由鉴权体系?【系列一】

咱们书接上回、、、正式开始.

bootstrap.js相关配置项及方法说明

/* 加载路由的方法,加载导航守卫的方法,初始化设置的方法 */
import { loadRoutes, loadGuards, setAppOptions } from '@/utils/routerUtil'
/* 请求响应拦截器,token鉴权 */
import { loadInterceptors, checkAuthorization } from '@/utils/request'
/* 获取用户信息的util */
import { loadUserInfo } from '@/utils/userInfoUtil'
/* 自定义的守卫函数 */
import guards from '@/router/guards'
/* 请求响应拦截器实现 */
import interceptors from '@/utils/axios-interceptors'

/**
 * 启动引导方法
 * 应用启动时需要执行的操作放在这里
 * @param router 应用的路由实例
 * @param store 应用的 vuex.store 实例
 * @param i18n 应用的 vue-i18n 实例
 * @param message 应用的 message 实例
 */
function bootstrap ({ router, store, i18n, message }) {
  // 设置应用配置
  setAppOptions({ router, store, i18n })
  // 加载 axios 拦截器
  loadInterceptors(interceptors, { router, store, i18n, message })
  // 加载路由
  loadRoutes()
  // 加载路由守卫
  loadGuards(guards, { router, store, i18n, message })
  if (checkAuthorization()) {
    loadUserInfo({ router, store, i18n, message })
  }
}

export default bootstrap

路由的加载与初始化设置 导航守卫设置

// @/utils/routerUtil
// 应用配置
const appOptions = {
  router: undefined,
  i18n: undefined,
  store: undefined
}

/**
 * 设置应用配置
 * @param options
 */
function setAppOptions (options) {
  const { router, store, i18n } = options
  appOptions.router = router
  appOptions.store = store
  appOptions.i18n = i18n
}

/**
 * 加载路由
 * @param routesConfig {RouteConfig[]} 路由配置
 */
function loadRoutes (routesConfig) {
  // 兼容 0.6.1 以下版本
  /** ************* 兼容 version < v0.6.1 *****************/
  if (arguments.length > 0) {
    const arg0 = arguments[0]
    if (arg0.router || arg0.i18n || arg0.store) {
      routesConfig = arguments[1]
      console.error('the usage of signature loadRoutes({router, store, i18n}, routesConfig) is out of date, please use the new signature: loadRoutes(routesConfig).')
      console.error('方法签名 loadRoutes({router, store, i18n}, routesConfig) 的用法已过时, 请使用新的方法签名 loadRoutes(routesConfig)。')
    }
  }
  /** ************* 兼容 version < v0.6.1 *****************/

  // 应用配置
  const { router, store, i18n } = appOptions

  // 如果 routesConfig 有值,则更新到本地,否则从本地获取
  if (routesConfig) {
    store.commit('account/setRoutesConfig', routesConfig)
  } else {
    routesConfig = store.getters['account/routesConfig']
  }
  // 如果开启了异步路由,则加载异步路由配置
  const asyncRoutes = store.state.setting.asyncRoutes
  if (asyncRoutes) {
    if (routesConfig && routesConfig.length > 0) {
      const routes = parseRoutes(routesConfig, routerMap)
      const finalRoutes = mergeRoutes(basicOptions.routes, routes)
      formatRoutes(finalRoutes)
      router.options = { ...router.options, routes: finalRoutes }
      router.matcher = new Router({ ...router.options, routes: [] }).matcher
      finalRoutes.forEach(v => {
        router.addRoute(v)
      })
    }
  }
  // 提取路由国际化数据
  mergeI18nFromRoutes(i18n, router.options.routes)
  // 初始化Admin后台菜单数据
  const rootRoute = router.options.routes.find(item => item.path === '/')
  const menuRoutes = rootRoute && rootRoute.children
  if (menuRoutes) {
    store.commit('setting/setMenuData', menuRoutes)
  }
}

/**
 * 加载导航守卫
 * @param guards
 * @param options
 */
function loadGuards (guards, options) {
  const { beforeEach, afterEach } = guards
  const { router } = options
  beforeEach.forEach(guard => {
    if (guard && typeof guard === 'function') {
      router.beforeEach((to, from, next) => guard(to, from, next, options))
    }
  })
  afterEach.forEach(guard => {
    if (guard && typeof guard === 'function') {
      router.afterEach((to, from) => guard(to, from, options))
    }
  })
}

此处路由相关的内容不必照搬我的代码,按你自己的项目需求来就可以了。下一期详细讲解导航守卫及如何在导航守卫内鉴权。