Vue Router 进阶,声明式 / 编程式导航 + 重定向 + 404 + 路由模式

Vue Router 是 Vue 单页应用的核心,但基础的页面切换只是入门 ------ 实际开发中还需要处理导航高亮、页面重定向、404 错误、路由传参等场景。本文结合思维导图,带你掌握 Vue Router 的进阶用法。

一、声明式导航:更优雅的页面跳转

声明式导航通过<router-link>标签实现(替代传统<a>标签),核心优势是自带 "导航高亮" 能力。

1. 导航高亮:自动标识当前路由

<router-link>会自动给当前激活的路由添加类名,默认类名是router-link-active(模糊匹配)和router-link-exact-active(精确匹配)。

(1)两个类名的区别

  • router-link-active:模糊匹配(如/goods会匹配/开头的路由);
  • router-link-exact-active:精确匹配(仅当路径完全一致时激活)。
    示例:
vue 复制代码
<template>
  <!-- 点击"商品页"时,/goods会同时激活router-link-active和router-link-exact-active -->
  <!-- 
  router-link: VueRouter 提供的全局组件
  必须提供 to 属性
  1. 会自动加 #
  2 可以很方便的实现导航高亮
  -->
  <router-link to="/">首页</router-link>
  <router-link to="/goods">商品页</router-link>
</template>

<style>
/* 
  router-link-active: 模糊匹配, 只要访问路径包含 a 标签的 href, 就会自动加上这个类名 (用得多)
  router-link-exact-active: 精确匹配, 必须要访问路径和 a 标签的 href 完全一致才会加上这个类名 (用得少)
 */
/* 自定义高亮样式 */
.router-link-exact-active {
  color: red;
  font-weight: bold;
}
</style>

(2)自定义高亮类名

若不想用默认类名,可通过active-classexact-active-class自定义:

javascript 复制代码
// 在index.js中
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

const router = new VueRouter({
  routes: [
  ],
  // 自定义模糊匹配的类名
  linkActiveClass: 'active',
  // 自定义精确匹配的类名
  linkExactActiveClass: 'exact-active',
})

export default router

使用时,只需要用自己定义的类名即可

vue 复制代码
<style>
a.active {
  background-color: yellow;
}
</style>

2. 声明式导航传参:携带数据跳转

query传参是将参数拼接在 URL 的查询字符串中(如/goods?id=1&name=苹果),特点是参数可见、可刷新保留。

(1) 基本用法

通过<router-link>to属性传递对象形式的query参数:

vue 复制代码
<template>
  <!-- 传参:query参数会拼接在URL后 -->
  <router-link 
    :to="{
      path: '/goods', // 目标路由路径
      query: { id: 1, name: '苹果' } // 传递的参数
    }">
    苹果详情
  </router-link>
  
  <!-- 或使用这种方式 -->
  <!-- <router-link :to="/goods?id=1&name=苹果">
    苹果详情
  </router-link> -->
</template>

(2)目标页面接收参数

在目标组件中,通过this.$route.query获取参数:

vue 复制代码
<!-- Goods.vue -->
<script>
export default {
  mounted() {
    console.log(this.$route.query.id); // 输出:1
    console.log(this.$route.query.name); // 输出:"苹果"
  }
};
</script>

(3)特点

  • 参数会显示在 URL 中,支持刷新页面后保留;
  • 适合传递非敏感、可选的参数(如列表筛选条件)。

3. 声明式导航传参:动态路由传参

动态路由传参是将参数嵌入路由路径中(如/goods/1),特点是参数隐藏在路径中、语义化更强。

(1)配置动态路由规则

先在路由配置中定义动态路由参数(以:开头):

javascript 复制代码
// router/index.js
const routes = [
  // 动态路由:id是参数名
  { path: '/goods/:id', name: 'Goods', component: Goods }
];

(2)声明式导航传递动态参数

通过<router-link>to属性传递动态参数:

vue 复制代码
<template>
  <!-- 方式1:直接拼接路径 -->
  <router-link to="/goods/2">香蕉详情</router-link>

  <!-- 方式2:结合命名路由(更灵活) -->
  <router-link 
    :to="{
      name: 'Goods', // 对应路由的name
      params: { id: 3 } // 传递动态参数
    }"
  >
    橙子详情
  </router-link>
</template>

(3)目标页面接收参数

在目标组件中,通过this.$route.params获取参数:

vue 复制代码
<!-- Goods.vue -->
<script>
export default {
  mounted() {
    console.log(this.$route.params.id); // 输出:2 或 3
  }
};
</script>

(4)特点

  • 参数隐藏在 URL 路径中,语义化更强(如/goods/1/goods?id=1更直观);
  • 适合传递必填的、标识性的参数(如商品 ID、用户 ID)。

4. 动态路由参数可选符:处理非必填参数

默认情况下,动态路由参数是必填的(如/goods/:id必须传入id,否则会匹配 404)。若需要参数可选,可在参数名后添加?(可选符)。

(1)配置可选动态路由

在路由规则的参数名后加?

javascript 复制代码
// router/index.js
const routes = [
  // id参数可选:/goods 和 /goods/1 都能匹配
  { path: '/goods/:id?', name: 'Goods', component: Goods }
];

(2) 声明式导航使用

可选择是否传递参数:

vue 复制代码
<template>
  <!-- 不传递id参数,匹配/goods -->
  <router-link to="/goods">商品列表</router-link>

  <!-- 传递id参数,匹配/goods/4 -->
  <router-link to="/goods/4">草莓详情</router-link>
</template>

(3)目标页面兼容处理

在目标组件中判断参数是否存在:

vue 复制代码
<!-- Goods.vue -->
<script>
export default {
  mounted() {
    const goodsId = this.$route.params.id;
    if (goodsId) {
      console.log('当前是商品详情,ID:', goodsId);
    } else {
      console.log('当前是商品列表');
    }
  }
};
</script>

二、重定向:页面跳转的 "快捷方式"

重定向用于将一个路由自动跳转到另一个路由(如访问/home时跳转到/),通过路由规则的redirect属性实现。

javascript 复制代码
// router/index.js 路由规则
const routes = [
  { path: '/', component: Home },
  // 访问/home时,重定向到首页
  { path: '/home', redirect: '/' },
  // 也可以重定向到命名路由(需给路由配置name)
  { path: '/old-goods', redirect: { name: 'Goods' } }
];

三、处理 404 页面:捕获无效路由

当用户访问不存在的路由时,需要显示 "404 页面"------ 通过通配符*匹配所有未定义的路由。

步骤:

1.创建 404 页面组件(如NotFound.vue);

vue 复制代码
<template>
  <div>
    <img src="https://img2.baidu.com/it/u=1515291965,518622767&fm=253&fmt=auto&app=138&f=PNG?w=500&h=294" alt="">
  </div>
</template>

<script>
export default {

}
</script>

<style scoped lang="less">
div {
  text-align: center;
  img {
    margin-top: 100px;
  }
}
</style>

2.在路由规则最后添加通配符路由:

javascript 复制代码
// router/index.js
import NotFound from '../views/NotFound.vue';

const routes = [
  { path: '/', component: Home },
  { path: '/goods', component: Goods },
  // 通配符*匹配所有未定义的路由
  { path: '*', component: NotFound }
];

此时访问/abc等无效路径,会自动渲染NotFound.vue

四、路由模式:控制 URL 的表现形式

Vue Router 有两种路由模式,决定 URL 的格式:

1. hash 模式(默认)

  • URL 中包含#(如http://localhost:8080/#/goods);
  • 优点:兼容性好(支持所有浏览器);
  • 缺点:URL 不够美观。

2. history 模式

  • URL 无#(如http://localhost:8080/goods
  • 优点:URL 更符合传统网站格式;
  • 缺点:需要后端配合(部署时需配置 Nginx/Apache,否则刷新页面会 404)。

配置方式:

javascript 复制代码
// router/index.js
const router = new VueRouter({
  mode: 'history', // 切换为history模式
  routes
});

五、编程式导航:通过 JS 控制跳转

编程式导航是通过 JavaScript 代码控制页面跳转的核心方式,而 Vue Router 中最常用的跳转逻辑可分为 path跳转和name跳转 两大类,每种方式又支持不同的传参策略。本文将这两种跳转方式与传参逻辑结合,帮你系统掌握编程式导航的用法。

1. 核心跳转方法:this.$router.push()

无论使用path还是name跳转,核心方法都是this.$router.push(),它接收一个路由地址参数(字符串或对象),并将新路由添加到浏览器历史记录中(支持后退)。

基础用法(无传参):

vue 复制代码
// 字符串形式(仅path跳转可用)
this.$router.push('/home');

// 对象形式(path/name跳转均支持)
this.$router.push({ path: '/home' }); // path跳转
this.$router.push({ name: 'Home' });  // name跳转

2. 方式 1:path 跳转(通过路径匹配)

path跳转直接通过路由的路径(如/goods)匹配目标页面,传参方式有两种:query传参和动态路由params传参。

(1)path 跳转 + query 传参(最常用)

参数以查询字符串形式拼接在 URL 后(如 /goods?id=1&name=苹果 ),适合传递非敏感、可选参数。

用法示例:

javascript 复制代码
this.$router.push({
  path: '/goods', // 目标路由路径
  query: { 
    id: 1, 
    name: '苹果',
    price: 5.99 
  }
});
// 最终URL:/goods?id=1&name=苹果&price=5.99

目标页面接收参数:

javascript 复制代码
// 目标组件中通过$route.query获取
mounted() {
  console.log(this.$route.query.id);    // 1
  console.log(this.$route.query.name);  // '苹果'
}

(2)path 跳转 + 动态路由 params 传参(需路由配置)

参数嵌入 URL 路径中(如/goods/1),适合传递标识性参数(如 ID),需在路由规则中定义动态参数(:开头)。

步骤 1:配置动态路由规则

javascript 复制代码
// router/index.js
const routes = [
  { path: '/goods/:id', component: Goods } // 定义动态参数id
];

步骤 2:path 跳转传参

javascript 复制代码
// 方式1:直接拼接路径(推荐)
this.$router.push(`/goods/${1}`); // 等价于 '/goods/1'

// 方式2:通过params对象传递(仅path为字符串时生效)
this.$router.push({
  path: '/goods',
  params: { id: 1 } // 解析为 '/goods/1'
});

目标页面接收参数:

javascript 复制代码
// 目标组件中通过$route.params获取
mounted() {
  console.log(this.$route.params.id); // 1
}

3. 方式 2:name 跳转(通过路由名称匹配)

name跳转通过路由规则中定义的name属性匹配页面(如name: 'Goods'),传参方式同样支持queryparams,且更推荐用于复杂场景。

(1)name 跳转 + query 传参

path跳转+query传参逻辑一致,参数显示在 URL 查询字符串中,但通过name匹配路由更易维护。

用法示例:

javascript 复制代码
// 步骤1:路由规则定义name
// router/index.js
const routes = [
  { path: '/goods', name: 'Goods', component: Goods }
];

// 步骤2:name跳转传参
this.$router.push({
  name: 'Goods', // 目标路由名称
  query: { 
    id: 2, 
    name: '香蕉' 
  }
});
// 最终URL:/goods?id=2&name=香蕉

目标页面接收参数:

javascript 复制代码
// 同样通过$route.query获取
console.log(this.$route.query.id); // 2

(2)name 跳转 + params 传参(推荐)

参数可嵌入路径(动态路由)或仅在内存中传递,无需手动拼接路径,灵活性更高。

步骤 1:配置带 name 的动态路由

javascript 复制代码
// router/index.js
const routes = [
  { path: '/goods/:id', name: 'Goods', component: Goods }
];

步骤 2:name 跳转传参

javascript 复制代码
this.$router.push({
  name: 'Goods',
  params: { 
    id: 2,           // 动态参数(会嵌入URL:/goods/2)
    type: 'fruit'    // 非动态参数(仅内存传递,刷新丢失)
  }
});

目标页面接收参数:

javascript 复制代码
// 动态参数和非动态参数均通过$route.params获取
mounted() {
  console.log(this.$route.params.id);   // 2(URL中可见)
  console.log(this.$route.params.type); // 'fruit'(仅内存中)
}
相关推荐
d111111111d2 小时前
C语言中static修斯局部变量,全局变量和函数时分别由什么特性
c语言·javascript·笔记·stm32·单片机·嵌入式硬件·学习
广州华水科技2 小时前
单北斗变形监测在水库安全中的应用与维护该如何实施?
前端
GIS好难学2 小时前
0帧起手《Vue零基础教程》,从前端框架到GIS开发系列课程
前端·vue.js·前端框架
李瑞丰_liruifengv2 小时前
使用 Claude Agent SDK 写一个 DeepResearch Agent
javascript·aigc·agent
行走的陀螺仪2 小时前
重绘和重排怎么触发?怎么优化?
前端·css·性能优化·css3·浏览器原理
尘世中一位迷途小书童2 小时前
项目大扫除神器:Knip —— 将你的代码库“瘦身”到底
前端·架构·代码规范
StarkCoder2 小时前
🚫求求你别再手动改类名了!Swift 自动混淆脚本上线,4.3 头发保卫战正式开始!
前端
LYFlied2 小时前
Vue Vapor模式与AI时代前端发展的思考:虚拟DOM与框架的未来
前端·vue.js·人工智能·前端框架
江公望2 小时前
VUE3 动态Prop 10分钟讲清楚
前端·javascript·vue.js