vue根据菜单信息动态添加路由

在某些情况,需要添加的路由不确定,需要从后端获取数据,并且后端更新相关的路由时,页面也能够立即渲染出来,这时候就需要使用动态路由。
例如商城后台项目,菜单中的很多路由都是不确定的,即使你写了10个路由,但是后端那边新增了10个路由,那么这时候设置动态添加路由后,就可以自动在第一时间创建出所有的路由,而不需要你手动的写了。

1、设置默认路由以及动态路由
① 这里需要注意动态路由和默认路由都需要加上name
② 动态路由的name建议和path保持一致,不然有可能会出现无限重定向
③ 默认路由的name不需要和path保持一致,取个合适的名字就好

import { createRouter, createWebHashHistory } from "vue-router";

//默认路由
const routes=[
  {
    path:'/',
    name:'admin',
    component:Admin,
  }
]

//动态路由
const asyncRoutes = [
  {
    path: '/',
    name: '/',
    component: Index,
    meta: {
      title: '后台首页'
    }
  }, {
    path: '/goods/list',
    name: '/goods/list',
    component: GoodList,
    meta: {
      title: '商品管理'
    }
  }, {
    path: '/category/list',
    name: '/category/list',
    component: CategoryList,
    meta: {
      title: '分类列表'
    }
  }
]

2、制作动态添加路由方法
这个方法需要用到递归,因为路由可能包含子路由,也就是一级导航和二级导航,就是可以一层一层的往下找,如果匹配到后端给的对应的路由,并且这个路由不存在,那就自动添加到动态路由中进行渲染。
思路:
① arr这个后端传过来的路由数组遍历后,找到他每一条路由(e.frontpath),然后再从动态路由(asyncRoutes)中查找里面的路由是否和后端传过来的arr路由匹配。
② 如果匹配并且这个路由不存在(!router.hasRoute(item.path)),那么利用嵌套路由(router.addRoute(‘admin’,item))进行添加。
③ 再次判断子路由(e.child)是否存在并且有数据,(这个child需要你查看后端传过来的数据,可能字段是不一样的),如果子路由有数据,那么再次执行findAndAddRoutesByMenus()这个方法,实现递归。

//router下面的index.js
import { createRouter, createWebHashHistory } from "vue-router";

export const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export const addRoutes = (menus)=>{
  const findAndAddRoutesByMenus = (arr)=>{
    arr.forEach(e => {
      let item = asyncRoutes.find(o=>o.path == e.frontpath)
      if(item && !router.hasRoute(item.path)){
        router.addRoute('admin',item)
      }
      if(e.child && e.child.length){
        findAndAddRoutesByMenus(e.child)
      }
    })
  }
  findAndAddRoutesByMenus(menus)
}

3、执行addRoutes ()方法
执行时机最好是获取到后端传来的路由数据之后,我这边是在全局前置守卫中利用vuex来获取数据,res.menu就是数据中的路由信息,那么在获取信息数据之后,执行addRoutes ()方法,并将res.menus传入方法中。

import { router, addRoutes } from '~/router'

router.beforeEach(async (to, from, next) => {
  if (token) {
    const res = await store.dispatch('getinfon')
    addRoutes(res.menus)
  }
})

4、特别要注意的一点
按照上述步骤完成后,你一刷新页面就会提示找不到页面,这里引用vue官方的原话:
动态路由主要通过两个函数实现。router.addRoute() 和 router.removeRoute()。它们只注册一个新的路由,也就是说,如果新增加的路由与当前位置相匹配,就需要你用 router.push() 或 router.replace() 来手动导航,才能显示该新路由。
思路:
① 在addRoutes 方法内创建一个hasNewRoute(是否有新的路由)变量,在动态添加路由后设置为true
② 在全局前置守卫中也定义相同的hasNewRoute变量,通过赋值的形式传递给hasNewRoute
③ 如果hasNewRoute为true,那么就手动跳转(next(to.fullPath))到对应的页面,否则直接next()

//router下面的index.js
import { createRouter, createWebHashHistory } from "vue-router";

export const addRoutes = (menus)=>{
  let hasNewRoute = false
  const findAndAddRoutesByMenus = (arr)=>{
    arr.forEach(e => {
      let item = asyncRoutes.find(o=>o.path == e.frontpath)
      if(item && !router.hasRoute(item.path)){
        router.addRoute('admin',item)
        hasNewRoute=true
      }
      if(e.child && e.child.length){
        findAndAddRoutesByMenus(e.child)
      }
    })
  }
  findAndAddRoutesByMenus(menus)
  return hasNewRoute
}
import { router, addRoutes } from '~/router'

router.beforeEach(async (to, from, next) => {
  let hasNewRoute = false
  if (token) {
    const res = await store.dispatch('getinfon')
    hasNewRoute = addRoutes(res.menus)
  }
  hasNewRoute ? next(to.fullPath) : next()
})
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值