vue-router 动态添加路由,二次添加遇到的问题

本文介绍了解决Vue-router在动态添加路由时遇到的重复问题,通过修改代码结构避免警告并提供了解决方案。

@[TOC] 修改记录

vue-router 动态添加路由,二次添加遇到的问题
问题(vue版本:2.6.2):
  • 因为路由根据登录角色获取的路由信息,如果退出后再次登录则需要重新获取路由信息
  • 因为addRoutes 给路由表中添加路由,导致有些路由信息重复报警告:Duplicate named routes definition
解决:
// constantRoutes是公共路由,如下:
export const constantRoutes = [{
	path: '/redirect',
	component: Layout,
	hidden: true,
	children: [{
		path: '/redirect/:path(.*)',
		component: (resolve) => require(['@/views/redirect'], resolve)
	}]
}]
// 将router.js下的index.js中的如下代码:
export default new Router({
	mode: 'hash', // 去掉url中的#
	scrollBehavior: () => ({
		y: 0
	}),
	routes: constantRoutes
})
// 修改为------------------------
export const createRouter = (routes) => new Router({
	mode: 'hash', // 去掉url中的#
	scrollBehavior: () => ({
		y: 0
	}),
	routes
})
export const router = createRouter(constantRoutes);

找到使用 addRoutes 方法的文件

// 将router 的引入如下
import router from './router'
// 修改为------------------------
import { router, createRouter,constantRoutes } from '@/router'

// 将router.addRoutes这段代码如下:
router.addRoutes(accessRoutes) // 动态添加可访问路由表
// 修改为------------------------
router.matcher = createRouter(constantRoutes).matcher; // 重置路由表
router.addRoutes(accessRoutes) ;// 动态添加可访问路由表
// accessRoutes:就是你请求到的路由信息的自定义字段
// 注意  router, createRouter,constantRoutes 要一一对应

注意: 这个时候并没有修改完成,你可能会发现如下错误
Error in render: "TypeError: Cannot read property 'matched' of undefined"
找到所有 import router from './router' 的文件。一般在都是main.js。

// 将如下代码:
import router from './router
//修改为------------------------
import {router} from './router'

主要是因为在修改router.js中的代码时,导出方式变更了,所以改掉即可。

如需学习Matcher,请看Vue Router中Matcher的初始化分析

如有错误,或疑问请留言,谢谢各位观看!

<think>我们参考了用户提供的多个引用,这些引用都集中在Vue-router如何响应路由参数变化的问题上。根据引用内容,主要有两种方法: 1. 使用watch监听$route对象的变化(引用[2][3][4]) 2. 使用导航守卫(引用[4][5]) 下面将详细说明这两种方法: ### 方法一:使用watch监听$route 当路由参数变化时,$route对象会更新,因此我们可以通过监听$route来执行相应的操作。 #### 示例代码 ```javascript export default { watch: { // 方法1:直接监听$route对象 '$route'(to, from) { // 这里可以比较to和from的参数,根据需要判断是否执行操作 if (to.params.id !== from.params.id) { // 参数变化后的处理,比如重新获取数据 this.fetchData(); } }, // 方法2:使用handler和immediate选项 '$route': { handler: 'fetchData', // 处理函数名(需要在methods中定义) immediate: true // 立即执行一次(在组件创建时) } }, methods: { fetchData() { // 从$route中获取参数 const id = this.$route.params.id; // 根据id获取数据等操作 } } }; ``` 注意: - 方法1可以比较新旧路由的参数,避免不必要的操作。 - 方法2使用`immediate:true`可以在组件创建时就执行一次`fetchData`,这样就不需要在`mounted`中再调用一次。 ### 方法二:使用导航守卫 导航守卫是Vue-router提供的钩子函数,可以在路由变化的不同阶段执行操作。对于响应路由参数变化,可以使用`beforeRouteUpdate`守卫。 #### 示例代码 ```javascript export default { beforeRouteUpdate(to, from, next) { // 路由参数变化,但组件被复用时调用 // 可以访问组件实例`this` if (to.params.id !== from.params.id) { this.fetchData(); // 重新获取数据 } next(); // 必须调用next() }, methods: { fetchData() { // 获取数据 } } }; ``` 注意: - `beforeRouteUpdate`在当前路由改变且组件被复用时调用(比如动态参数路径`/user/:id`,从`/user/1`跳转到`/user/2`)。 - 在这个守卫中可以访问组件实例`this`,但必须调用`next()`来继续导航。 ### 两种方法的比较 - **watch监听$route**:简单直观,适用于大多数情况,特别是当组件不会被复用时(比如同一个路由参数变化,但组件不会被复用的情况)。 - **导航守卫**:更适用于需要确保在路由更新过程中完成某些操作(如数据获取)后再进入新路由的情况。 ### 总结 在Vue-router中响应路由参数变化,有两种常用方法: 1. 使用`watch`监听`$route`对象的变化,然后执行相应的操作。 2. 使用`beforeRouteUpdate`导航守卫,在组件复用时执行操作。 根据具体场景选择合适的方法。通常,如果组件不会被复用(例如,不同的路由对应不同的组件),使用`watch`即可;如果组件会被复用(例如,动态参数路径),则使用`beforeRouteUpdate`更为合适。 §§相关问题§§ 1. Vue-router中如何监听查询参数(query)的变化? 2. 在watch中监听$route和使用导航守卫有什么区别? 3. 什么是Vue-router的组件复用?在什么情况下会发生组件复用? 4. 除了watch和导航守卫,还有哪些方式可以响应路由变化? </think>### Vue-router 响应路由参数变化的方法 在 Vue.js 中,当使用 Vue-router 时,响应路由参数变化主要有以下两种核心方法: #### 1. **使用 `watch` 监听 `$route` 对象(推荐)** 通过监听路由对象的变化,可以在参数更新时触发自定义逻辑(如数据加载)。 ```javascript export default { watch: { // 方法1:直接比较新旧路由参数 '$route'(to, from) { if (to.params.id !== from.params.id) { this.id = to.params.id; this.loadData(); // 重新加载数据 } }, // 方法2:直接调用处理函数(支持立即执行) '$route': { handler: 'loadData', // 处理函数名 immediate: true // 组件创建时立即执行一次 } }, methods: { loadData() { const id = this.$route.params.id; // 根据 id 请求数据 } } } ``` **特点**: - 灵活控制逻辑(如参数对比) - `immediate: true` 可在组件初始化时自动加载数据 [^2][^3] --- #### 2. **使用导航守卫 `beforeRouteUpdate`** 适用于组件复用时触发的场景(如动态路由 `/user/:id` 跳转)。 ```javascript export default { beforeRouteUpdate(to, from, next) { if (to.params.id !== from.params.id) { this.id = to.params.id; this.loadData(); // 重新加载数据 } next(); // 必须调用 next() 继续导航 }, methods: { loadData() { /* 获取数据 */ } } } ``` **特点**: - 专为动态参数路由设计 - 可访问组件实例 `this` - **注意**:必须调用 `next()` [^4][^5] --- ### 两种方法的区别 | **场景** | `watch: $route` | `beforeRouteUpdate` | |-----------------------------|-------------------------------|-------------------------------| | **组件复用**(动态路由) | ✅ 适用 | ✅ 专为复用场景设计 | | **初次加载** | 需 `immediate: true` 触发 | ❌ 仅在路由更新时触发 | | **逻辑控制** | 可自定义参数对比 | 需手动对比参数 | | **代码位置** | 在 `watch` 选项中 | 在导航守卫钩子中 | > **关键原因**:Vue-router 会复用相同组件实例(如 `/user/1` → `/user/2`),导致生命周期钩子(如 `mounted`)不会重新执行 [^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值