动态路由的学习

282 阅读2分钟

Vue后台管理项目经常有权限控制,不同角色使用不同权限,常用方法就是用addRoutes来动态添加路由,但有两个问题是官方文档上找不到解决方案的

  • 角色切换,addRoutes提示有重复的路由,无法删除之前角色的路由
    • 使用router.matcher = new Router().matcher替换掉旧的路由
  • 刷新页面,动态路由消失,提示404
    • 将404页面放在动态路由中加载,即获取动态路由后,push上404页,这样就完美解决了
//在router模块的index.js对路由进行拆分

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

Vue.use(Router)

//常量路由(即所有人都能看到的路由)
export const constRoutes = []
//异步理由:不同的用户(角色),需要过滤筛选出的路由,称之为异步路由
export const asyncRoutes = []
// 404界面,一定要放在最后
export const anyRoutes = {path'*',redirect:'/',hidden:true}

//定义创建路由的函数
const createRouter = () => new Router({
  scrollBehavior: () => ({ y: 0 }),//路由跳转回到顶部
  routes: constantRoutes
})
//创建路由
const router = createRouter()
//在store获取用户信息的模块中
import { constantRoutes,asyncRoutes,anyRoutes } from '@/router'
import router from '@/router'

const getDefaultState = () => {
  return {
    //用户最终需要展示全部路由
    allRoutes:[]
  }
}

const state = getDefaultState()

const actions = {
    async getUserInfo(){
         if (result.code === 200) {
          const { data } = result
          //服务器返回的权限信息【根据不同的角色:返回的路由权限信息】
          const { routes } = data
          commit('SET_ASYNCROUTES', computedAsyncRoutes(asyncRoutes,routes))
          return 'ok'
        } else {
          return Promise.reject(new Error('fail'))
        }
  },
    
}

const mutations = {
    SET_ASYNCROUTES: (state,asyncRoutes) => {
        // 将该角色能访问的异步路由与常量路由及404路由合并
        state.allRoutes = constRoutes.concat(asyncRoutes,anyRoutes)
        router.matcher = new Router().matcher //清空之前的旧路由
        router.addRoutes(state.allRoutes) //
    }
}

// 计算出当前用户所能访问的路由
function computedAsyncRoutes(asyncRoutes,routes){
    // 返回该角色能访问到的路由数组
    return asyncRoutes.filter(item => {
        // routes数组中的内容是该角色的所能访问的路由的名字
        if(routes.indexOf(item.name) != -1){
            //递归
            if(item.children && item.children.length){
                // 如果有子路由,子路由中能访问的路由也需要计算
                item.children = computedAsyncRoutes(item.children,routes)
            }
            return true
        }
    })
}

注意: 在vue-router 3.5.0版本中,router.addRoutes被标记为不推荐的API,建议使用 router.addRoute 在vue-router 4.x 中,router.addRoutes被删除,只能使用 router.addRoute