vue3的动态路由

这两天项目慢慢成型,要求把路由改为动态路由,期间遇到了几个问题,在此记录一下
因为项目是其中值得注意的几个问题有

  1. 配置动态路由的步骤
  2. 配置过程中route的component的引入
  3. 配置完成后,页面刷新白屏

1. 配置动态路由的步骤

步骤都是在路由守卫中完成的,首先判断用户是否登录,登录成功后再判断vuex中用来存放route的list是否有值,没有值的话调vuex中的接口请求路由数据,
然后拿到路由数据后,配置成route格式,用route的addRoute来加动态路由
(vue-router 4.0 取消了 addRouters 设置动态路由只能使用 addRouter)
以下是路由守卫的代码

import storage from 'store'
import store from '@/store'
import { whiteList, manageRouterMap } from './basics.router'
import { Router, RouteRecordRaw } from 'vue-router'
import { generateIndexRouter } from '@/utils/util'
const loginPath = '/login'
const defultPath = '/'

router.beforeEach((to, from, next) => {
    const param = getUrlParms("token"); //调用函数即可
    if (param) {
      storage.set('token', param)
    }
    //从这里开始,以上算是业务代码
    if (storage.get('token')) {
      if (to.path === loginPath) {
        next({ path: defultPath })
      } else {
      //判断vuex中的routers是否有值
        if ( store.state.user.routers.length == 0) {
          // ***********************动态路由注释***********************
          //调接口拿到路由数据
          store.dispatch('user/menu').then(e => {
            let menuData = e.result.menu
            if (menuData === null || menuData === '' || menuData === undefined) {
              return
            }
            //这块是处理拿到的接口数据,在另一个ts里
            let constRoutes=generateIndexRouter(menuData)
            //处理完成后,调vuex中更新routers的方法更新一下routers
            store.dispatch('user/UpdateAppRouter', { constRoutes }).then((e) => {
            //更新后加入route
              router.addRoute(e[0])
            })
             next({...to,replace:true})
          })
        } else {
          next()
        }
      }
    } else {
      if (whiteList.includes(to.path)) {
        next()
      } else {
        // window.location.href = window._CONFIG['loginURL']
        next({ path: loginPath, query: { redirect: to.fullPath } })
      }
    }
  }

2.配置路由数据中遇到的关于component引入的问题

vue3+ts+vite的项目,关于路由component的引入,找了很多方法,最后发现就下面代码中的有效

import layout from '/src/layout/index.vue'
const modules = import.meta.glob('/src/views/**/*.vue')

// 生成首页路由
export function generateIndexRouter(data) {
    let indexRouter: any = [{
        path: '/',
        name: 'planManage',
        component: layout,
        meta: {
            title: '首页'
        },
        redirect: '/planManage',
        children: [
            ...generateChildRouters(data)
        ]
    },
    // {
    //     'path': '/:pathMatch(.*)*',
    //     'redirect': '/404',
    //     'hidden': true
    // }
]
    return indexRouter
}
function generateChildRouters(data) {
    console.log('data',data);
    
    let routers = []
    for (let item of data) {
      let menu = {
        path: item.path,
        name: item.name,
        meta:item.meta,
        component: modules[`/src/views${item.path}/index.vue`],
        // component: () => import(`/src/views/planManage/index.vue`),
        children: [],
  
      }
      if (item.children && item.children.length > 0) {
        menu.children = [...generateChildRouters(item.children)]
    }
      routers.push(menu)
    }
    return routers
  }

3.配置完成后刷新页面白屏的问题

白屏的出现主要是跟next()有关系
详见这两篇
vue3中的beforeEach里面的next函数—刷新页面导致白页

vue3 addRoute 动态路由 页面刷新后 路由失效 [Vue Router warn]: No match found for location with path

<think>好的,用户想了解Vue3动态路由的实现和使用方法。我需要先回忆一下Vue3动态路由相关知识,并确保信息准确。 首先,动态路由通常用于权限管理,根据用户角色加载不同的路由Vue3中使用Vue Router 4.x版本,和Vue2的写法有些不同。记得动态路由的实现步骤大概包括:定义静态和动态路由路由守卫处理、调用API获取权限数据、过滤生成可访问路由、使用addRoute添加路由等。 用户提供的引用内容里提到了动态路由模板、路由前置守卫和工具类,这些应该是关键部分。需要参考这些结构来组织回答。例如,引用[1]中提到了permission.js作为路由前置守卫,store使用vuex存储状态,util里有动态添加路由的工具类。引用[2]展示了路由配置的例子,包括登录、注册和home路由,可能动态添加子路由到Home.vue。 接下来要分步骤说明实现流程。可能需要先创建静态路由(如登录、注册等无需权限的页面),然后处理动态部分。在路由前置守卫(permission.js)中,判断用户是否登录,若已登录则获取用户权限信息,生成对应的动态路由,并通过addRoute方法添加到路由器实例中。同时,需要注意避免重复添加路由,可以通过在vuex中存储状态来判断是否已加载。 另外,动态路由的数据结构通常由后端返回,可能包含路由的path、name、component路径等信息。前端需要将component字段转换为实际的组件引用,可以使用() => import组件的方式实现懒加载。 可能还需要处理404页面,将其放在路由配置的最后,否则动态路由可能无法正确匹配。同时,添加路由后可能需要跳转到目标路径,解决刷新后空白页的问题。 用户可能想知道具体的代码示例,比如如何定义路由,如何过滤路由,如何添加。还需要提到注意事项,比如路由顺序、刷新处理、路由元信息的作用等。 最后,生成相关问题,帮助用户深入理解,比如动态路由的应用场景、如何与后端配合、权限控制方法、路由缓存问题等。要确保问题相关且有引导性。</think>### Vue3动态路由实现与使用详解 #### 一、核心实现原理 动态路由的核心是通过`router.addRoute()`方法实现运行时路由注入,结合路由守卫控制权限加载流程[^1]。典型应用场景包括后台管理系统的菜单权限控制和多角色访问控制。 #### 二、实现步骤分解 1. **路由结构划分** ```javascript // router/index.js const staticRoutes = [ { path: &#39;/login&#39;, component: () => import(&#39;@/views/Login.vue&#39;) }, { path: &#39;/404&#39;, component: () => import(&#39;@/views/404.vue&#39;) } ] const dynamicRoutes = [ { path: &#39;/dashboard&#39;, component: Layout, meta: { requiresAuth: true }, children: [ // 动态路由将在此处注入 ] } ] ``` 2. **权限验证守卫** ```javascript // permission.js router.beforeEach(async (to, from, next) => { if (hasToken()) { if (isFirstLoad) { const { roles } = await store.dispatch(&#39;user/getUserInfo&#39;) const accessRoutes = await generateRoutes(roles) accessRoutes.forEach(route => router.addRoute(route)) next({ ...to, replace: true }) // 解决刷新空白问题 } else { next() } } else { if (whiteList.includes(to.path)) next() else next(`/login?redirect=${to.path}`) } }) ``` 3. **路由数据转换** ```javascript // utils/routeConverter const modules = import.meta.glob(&#39;../views/**/*.vue&#39;) export function filterAsyncRoutes(routes) { return routes.map(route => ({ ...route, component: modules[`../views${route.component}.vue`], children: route.children ? filterAsyncRoutes(route.children) : [] })) } ``` #### 三、完整工作流程 1. 用户登录获取token 2. 触发路由守卫检查权限 3. 调用接口获取用户路由配置 4. 转换路由组件路径为实际引用 5. 动态注入有效路由 6. 跳转目标页面 #### 四、关键注意事项 1. **路由顺序**:404页面必须最后注册 2. **组件加载**:使用Webpack的魔法注释实现分包 ```javascript component: () => import(/* webpackChunkName: "dashboard" */ &#39;@/views/Dashboard.vue&#39;) ``` 3. **状态保持**:通过vuex存储已加载路由标识 4. **刷新处理**:需在app.vue中持久化路由状态 ```javascript // App.vue onMounted(() => { store.dispatch(&#39;routes/initRoutes&#39;) }) ``` #### 五、扩展优化方案 - **路由缓存**:结合`<keep-alive>`实现组件状态保持 - **菜单生成**:通过`router.getRoutes()`获取完整路由表 - **权限验证**:使用路由元信息进行细粒度控制 ```javascript meta: { permissions: [&#39;admin&#39;, &#39;editor&#39;] } ``` ```typescript // 完整TS类型定义 declare interface RouteMeta { title?: string requiresAuth?: boolean permissions?: string[] icon?: string } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值