结合vuex实现动态路由的路由鉴权,根据不同的用户,展示不同的权限列表,实现动态的路由鉴权

  • Post author:
  • Post category:vue




1.对整体的路由结构进行整理,分为任意路由(都可以看的路由),404路由(无法访问的路由),以及异步路由(根据不同权限展示不同路由组件)

代码如下

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

Vue.use(Router)

/* Layout */
import Layout from '@/layout'

// 异步路由
export const asyncRouter = [
  {
    path: '/product',
    component: Layout,
    name: 'Product',
    meta: { title: '商品管理', icon: 'el-icon-goods' },
    children: [
      {
        path: 'trademark',
        name: 'TradeMark',
        component: () => import('@/views/product/tradeMark'),
        meta: { title: '品牌管理' }
      },
      {
        path: 'attr',
        name: 'Attr',
        component: () => import('@/views/product/Attr'),
        meta: { title: '平台属性管理' }
      },
      {
        path: 'spu',
        name: 'Spu',
        component: () => import('@/views/product/Spu'),
        meta: { title: 'Spu管理' }
      },
      {
        path: 'sku',
        name: 'Sku',
        component: () => import('@/views/product/Sku'),
        meta: { title: 'SKu管理' }
      },
    ]
  },
]

// 任意路由
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },

  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },

  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [{
      path: 'dashboard',
      name: 'Dashboard',
      component: () => import('@/views/dashboard/index'),
      meta: { title: '首页', icon: 'dashboard' }
    }]
  },
]

// 404路由
export const anyRoute = [
  // 404 page must be placed at the end !!!
  { path: '*', redirect: '/404', hidden: true }
]



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

const router = createRouter()

export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

export default router



2.在vuex内对整体的数据进行处理


state内的值
const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    avatar: '',
    routes:[],
    buttons:[],
    roles:[],
    // 对比之后需要展示的路由
    resultRoutes:[],
    // 用户展示的全部路由
    retultAllRoutes:[]
  }
}



2.1 在登录过后拿到用户的数据,这个数据内有routes的相关内容,在mutations中进行操作
  // 存储用户信息
  setUserInfo: (state,userInfo) => {
    // 菜单权限信息
    state.routes = userInfo.routes
  },
      


2.2 在actions中存储数据
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token).then(response => {
        const { data } = response
        console.log(data);
         //调用setUserInfo,储存routes的信息
        commit('setUserInfo',data)
         //这里是对比动态鉴权的信息,把筛选出来的数据,放在state内,后面的方法在后面讲解
        commit('setResultRoutes', computedAsyncRoute(asyncRouter,data.routes))
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

上面的data数据是这样的

请添加图片描述



2.3 在router把所有的路由都引入过来
import { anyRoute, asyncRouter, resetRouter, constantRoutes } from '@/router'


2.4通过递归,筛选出data.routes数据中 他所拥有的路由名字,把这个名字与 我们的路由进行一个对比,如果说

asyncRouter

动态路由里面的名字在这个data.routes中,就给他筛选出来,并返回。
这里面的asyncRouter是路由表里面的动态路由,这里的routes是登录后获取用户信息里面data.routes
const computedAsyncRoute = (asyncRouter, routes) => {
  // 这里的item就是路由的大对象
 return asyncRouter.filter(item => {
    // 不等于-1就是包含有这个名字
    if (routes.indexOf(item.name) != -1){
        //通过递归筛选出children属性
      if(item.children && item.children.length){
        item.children = computedAsyncRoute(item.children, routes)
      }
      return true
    }

  })
}


3.所有的数据筛选出来之后,我们需要引入router
import router from '@/router'


3.1在mutations内计算最终我们需要展示的路由
  // 最终计算出来的异步路由
  setResultRoutes: (state, resultRoutes) => {
    state.resultRoutes = resultRoutes
    // 计算用户需要展示的全部路由 通过concat把所有的路由都合并
    state.retultAllRoutes = constantRoutes.concat(state.resultRoutes, anyRoute)
    // 给路由添加新路由
    router.addRoutes(state.retultAllRoutes)
  }



版权声明:本文为m0_56986233原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。