天天看点

vue 动态路由实现

vue开发中,第二个问题就是实现动态路由,根据后端权限配置获取对应的路由,最终生成对应的菜单。如下:

1、菜单接口返回结果的数据结构

[{
	"url": "/system",
	"code": "sysmng",
	"name": "系统管理",
	"icon": "system",
	"children": [{
		"url": "menu",
		"code": "sysmenumng",
		"name": "菜单管理",
		"icon": "menu",
		"children": [],
		"parent": "menu"
	}],
	"parent": ""
}]
           

2、实现菜单接口

import axios from '../../../axios'

// 获取导航菜单树
export const fetchSidebarMenu = () => {
  return axios({
    url: '/system/sidebar',
    method: 'get'
  })
}
           

3、在store中调用菜单接口,并根据结果转换成动态路由列表

function buildRouters(routers, menutree) {
  if (!menutree) {
    return
  }
  menutree.forEach(function(item) {
    var routerItem = {}
    if (!item.parent) {
      routerItem.component = Layout
      routerItem.path = item.url
      if (routerItem.path.substring(0, 1) !== '/') {
        routerItem.path = '/' + routerItem.path
      }
    } else {
      routerItem.path = item.url
      let cnt = item.component
      routerItem.component = () => import(`@/views/${cnt}`)
    }
    routerItem.name = item.code
    routerItem.meta = { 'title': item.name, 'icon': item.icon }
    routerItem.hidden = item.hidden || false
    routerItem.alwaysShow = false
    routerItem.children = []
    routers.push(routerItem)
    buildRouters(routerItem.children, item.children)
  })
}

const actions = {
  generateRoutes({ commit }) {
    return new Promise((resolve, reject) => {
      fetchSidebarMenu().then(response => {
        let accessedRoutes = []
        const { data } = response
        buildRouters(accessedRoutes, data)
        accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
        commit('SET_ROUTES', accessedRoutes)
        resolve(accessedRoutes)
      }).catch(error => {
        reject(error)
      })
    })
  }
}
           

4、在router.beforeEach中拦截,获取动态路由

const hasGetUserInfo = store.getters.user
      if (hasGetUserInfo) {
        const hasPermissionRouters = store.getters.permission_routes;
        if(hasPermissionRouters.length === 0){
          const permissionRouters = await store.dispatch('permission/generateRoutes');
          router.options.routes = store.getters.permission_routes;
          router.addRoutes(store.getters.permission_routes);
          next({ ...to, replace: true })
        }else{
          next();
        }
      }