vue动态添加权限路由

在做后台系统时一般都会涉及到权限控制的问题,目前公司项目的处理是根据后端返回的权限表,动态添加路由来控制权限

这里先说一下整体的思路:我们先把一份整体的路由表数据给到后端,后端根据用户的权限,筛选返回其中的部分路由数据,我们根据接口返回的数据进行动态添加路由以及菜单的渲染,

以下是具体步骤:

1、在router文件夹里,添加menuData.js,这里面是需要给到后端的完整的权限表数据,具体格式由前端和后端沟通确定,这里仅做参考

const menuData = [
  // 用户管理===一级导航,不做跳转
  {
    title: '用户管理', // 标题
    icon: 'ico-aside2', // icon
    path: '1', // 路由路径
    name: '', // 路由别名
    component: '', // 路由挂载组件
    redirect: '', // 路由重定向地址
    children: [ // 当前路由下的子路由
      {
        title: '客户',
        icon: '',
        path: 'customer',
        name: 'Customer',
        component: 'Customer',
        redirect: 'customer-list',
        children: [
          {
            title: '客户列表',
            icon: '',
            path: 'customer-list',
            name: 'CustomerList',
            component: 'CustomerList',
            redirect: '',
            children: []
          },
          {
            title: '客户详情',
            icon: '',
            path: 'customer-details',
            name: 'CustomerDetails',
            component: 'CustomerDetails',
            redirect: '',
            children: []
          }
        ]
      }
    ]
  },
  // 系统设置===一级导航,不做跳转
  {
    title: '系统设置', // 标题
    icon: 'ico-aside5', // icon
    path: '2', // 路由路径
    name: '', // 路由别名
    component: '', // 路由挂载组件
    redirect: '', // 路由重定向地址
    children: [
      {
        title: '后台用户管理',
        icon: '',
        path: 'account',
        name: 'Account',
        component: 'Account',
        redirect: 'account-list',
        children: [
          {
            title: '后台用户管理列表',
            icon: '',
            path: 'account-list',
            name: 'AccountList',
            component: 'AccountList',
            redirect: '',
            children: []
          }
        ]
      }
    ]
  }
]

export default menuData

2、参考element-admin的权限控制,router文件夹里index.js修改如下:

import Vue from 'vue'
import Router from 'vue-router'
import { routerComponents } from './routerComponents' // 路由组件
import { constantRoutes, asyncRoutes, asyncRoutesCommon, errorRoute } from './constantRoutes' // 默认路由表

Vue.use(Router)

// 创建 Router实例
const createRouter = (clear = false) => new Router({
  // scrollBehavior: () => ({ y: 0 }),
  mode: 'history',
  routes: clear ? [] : constantRoutes
})

const router = createRouter()

// 重置路由
export function resetRouter (clear = false) {
  const newRouter = createRouter(clear)
  router.matcher = newRouter.matcher // reset router
}

// 添加路由
export function addRouter (menuData) {
  return new Promise(async (resolve, reject) => {
    /** 在这里写自己的逻辑 S */
    // 去掉一级导航,保留二级、三级导航
    let childList = []
    menuData.map(item => {
      childList.push(item.children)
    })
    childList = [].concat.apply([], childList)
    // 筛选生成动态路由表
    const tempRoutes = handleRoutesTable(childList)
    asyncRoutes[0].children = asyncRoutesCommon.concat(tempRoutes)
    /** 在这里写自己的逻辑 E */

    // 清空路由
    resetRouter(true)
    // 重新添加路由
    const newRoutes = [...constantRoutes, ...asyncRoutes, ...errorRoute]
    router.options.routes = newRoutes
    router.addRoutes(newRoutes)
    // console.log(newRoutes)
    resolve()
  })
}

// 过滤权限路由
function handleRoutesTable (childList) {
  let child = []
  if (childList.length === 0) return child
  childList.map((item, idx) => {
    child.push({
      path: item.path,
      name: item.name,
      meta: { title: item.title },
      component: routerComponents[item.component],
      redirect: item.children.length ? item.path + '/' + item.children[0].path : '',
      children: []
    })
    if (item.children.length) {
      child[idx].children = handleRoutesTable(item.children)
    }
  })
  return child
}

export default router

tips:我把引用的路由组件分离到routerComponents.js里去了,如图:
在这里插入图片描述
tips:import { constantRoutes, asyncRoutes, errorRoute } from './constantRoutes' // 默认路由表
项目需要设置默认的路由表,比如登录页,404页面,其他不需要权限就能进入的页面

在这里插入图片描述

3、把后端返回的权限数据放在vuex里,方便后面使用,在全局路由拦截beforeEach里面判断,如果有则next(),没有则在store的actions.js里重新请求权限接口

在这里插入图片描述
actions.js如下

import Vue from 'vue'
import router from '../router'
import store from './index'

// import menuData from '../router/menuData' // 使用动态路由时注释这行

export default {
  getPermissionList: ({commit}) => {
    // 这里是为了防止重复获取
    if (store.state.mutations.routes !== null) return

    // 请求 权限列表 接口
    Vue.prototype.$api.pGetMenu({
      uid: store.state.mutations.userId, // 账号id
      token: store.state.mutations.userToken // 登录token
    }).then(response => {
      console.log(response)
      commit('updatePermissionList', response.data)
    }).catch(error => {
      console.log(error.response)
      Vue.prototype.$msgbox.alert(error.response.data.message, {
        callback: action => {
          if (error.response.data.message === 'token验证失败') {
            router.replace({ path: '/login' })
          }
        }
      })
    })
  }
}

mutations.js如下

import getters from './getters.js'
import { addRouter } from '@/router/index'

const state = {
  routes: null
}

const mutations = {
  /** 权限控制 S */
  updatePermissionList (state, menuData) {
    state.routes = menuData
    addRouter(menuData)
  }
  /** 权限控制 E */
}

export default {
  state,
  mutations,
  getters
}

4、根据vuex里的权限数据,动态渲染侧边栏菜单,这里就不做展示了

====================================

至此,vue根据后端返回权限数据,动态添加路由就结束了,感谢大哥 @_Delete 的技术支持,让我顺利搞完了权限控制这一块!
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值