vue3 动态路由设计

从后端获取路由数据,将该请求放置在路由守卫(router.beforeEach)next的前面,阻塞next(),当动态组件添加好了在进入页面。

import { createRouter, createWebHistory } from 'vue-router'
// 基础路由 一般回放一个Login页面的对象
import { baseRoutes } from '@/router/basicRoutes'
import {  getUsermMenu } from "@/api";
 
// 在js/ts里面使用pinia,需要这么使用,多导出一个Pinia,这里就不展开说了,大家自行百度
import { routerListAddCountStore, routerListStore } from '@/stores/index'
import pinia from '@/stores/index'
const routerListAddCountV = routerListAddCountStore(pinia)
const routerListStoreV = routerListStore(pinia)
 
 
 
// 创建路由对象
let router = createRouter({
  // 路由模式hash
  // history:  createWebHashHistory(),
  history: createWebHistory(),
  routes: [...baseRoutes]
})
 
 
// 配置路由守卫
router.beforeEach((to, from, next) => {
  //  routerListAddCountV.routerListAddCount 控制整个项目只会请求一次后端路由 (请求后这个Pinia+=1就行了,简单判断)
  // routerListAddCountV.routerListAddCount 是 pinia
  if (routerListAddCountV.routerListAddCount >= 1) {
    console.log('我走不请求数据')
    next()
 
  } else {
    console.log('我走请求数据')
    // 这个是后端请求路由
    // !!!!!第一个知识点来了,如果你想阻塞next,你必须使用.then的方式调用,将next,放在.then中,看别人是这么解释的,next只能放在同步逻辑中,你写settiomeout 和 async await是不行的。
    getUsermMenu().then(res => {
      // 路由
      let TempRouterList = res.data.menuList
      // !!!!第二个知识点来了,我们的路由都是使用懒加载的,但是后端直接传过来()=》一个箭头函数是不能用的,所以我们要使用vue3(vite)的写法import.meta.glob,注意webpack不是这么写的,webpack的话需要自己去查一下。
      //   ../views/*/*.vue  这个的意思就是会将views/任意/任意.vue 复合这个格式的vue转换成箭头函数
      const modules = import.meta.glob(['../views/*/*.vue', '../views/*/*/*.vue'])
 
      // 这一段代码的意思就是
      TempRouterList.forEach(element => {
        // 具体的xi
        //  拆解一下    element.component是后端传过来的,是 '/home/layout.vue'
        //  加上 ../views  相当与是补全一下    ,这里用../(相对路径) 是因为不能写@(绝对路径)    
        // 最后打印 element.component  出来是    () => import("/src/views/home/layout.vue")  是这样的
        element.component = modules[`../views${element.component}`]
        if (element?.children.length > 0) {
          // 如果有嵌套路由也记得 懒加载一下
          element.children.forEach(Sonelement => {
            Sonelement.component = modules[`../views${Sonelement.component}`]
          })
        }
        // !!!!第三个知识点,  router就是上面创建的router 一页代码直接使用,  我们先说addRoute这个方法。就是将这个路由关系加进去我们路由的一个方法,添加一个最大的父级即可
        router.addRoute(element)
      });
 
      // !!!第四个知识点,404页面必须放在我们动态拿来的数据后面,如果放在前面会先匹配404
      let Route404 = {
        path: '/404',
        component: modules[`../views/404/index.vue`],
        name: '404',//命名路由
        meta: {       // 增加
          title: '丢失页面',
          show: false
        }
      }
      // 找不到的页面
      let ANyRoute = {
        path: '/:pathMatch(.*)*',
        redirect: '/404',
        name: 'Any',
        meta: {       // 增加
          title: '任意',
          show: false
        }
      }
 
      router.addRoute(Route404)
      router.addRoute(ANyRoute)
 
      TempRouterList.push(Route404)
      TempRouterList.push(ANyRoute)
 
      // 这个是将我们编辑好的这个路由数组,加入到pinia中,渲染的左侧菜单的时候使用这个Pinia就行
      routerListStoreV.setRouterList(TempRouterList)
      // 这个就是最开始判断》=1的哪个逻辑,这里面其实就是个pinia,pinia的方法是  +=1,这样加载过一次后,就会走不请求的判断
      routerListAddCountV.setRouterListAddCount()
 
  // !!!第5个知识点, router.getRoutes() 可以获取到你最新addrouter的注册路由, router.opetion并不是最新的
      let newRoutes = router.getRoutes()
      //  默认去第一个
      let goUrl = newRoutes[0].path
 
      // 如果被注册就去注册的
      newRoutes.some(item=>{
        if(item.path == to.path){
          goUrl = to.path
          return true
        }
      })
 
      // !!!第6个知识点来了,当你使用addroute加入,并用光杆next(),是会白屏的!必须加上replace: true,这个官方的解释就是等路由更新好再跳转的意思。
      next({ path: goUrl, replace: true })
 
    })
  }
});
 
 
 
 
 
 
 
 
// 配置路由对象
export default router

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值