源本科技 | 码上会

Vue3 动态路由

2026/04/23
21
0

引言

动态路由匹配是 Vue Router 4 的核心功能,允许将 URL 中的部分路径定义为动态参数,传递给对应组件。通过在路由路径中使用 :?* 等符号定义动态段,可捕获任意路径值并注入组件上下文,大幅提升应用的灵活性与可扩展性,适配商品详情、用户中心等动态页面场景。

动态路由匹配

在实际开发中,我们常需要让同一个组件匹配多个规则相似的 URL 地址。例如商品详情组件,需要根据不同的产品 ID 渲染对应数据。
Vue Router 4 通过 路径参数 实现该能力,路径参数使用 : 标记,会被提取为 params 对象传递到组件中。

路径参数

路径参数是动态路由的基础用法,用于匹配固定结构的动态 URL 片段。

  • 路由配置示例

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router';
import Product from '../components/Product.vue';

// 路由规则配置
const routes: Array<RouteRecordRaw> = [
  {
    // 定义动态参数 id
    path: '/product/:id',
    // 命名路由(推荐使用,便于编程式导航)
    name: 'Product',
    component: Product
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;
  • 产品详情组件 src/components/Product.vue

<template>
  <div class="product-detail">
    产品详情,产品 ID:{{ productId }}
  </div>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router';
import { computed } from 'vue';

// 获取当前路由实例
const route = useRoute();
// 计算属性获取动态参数(TS 类型断言)
const productId = computed(() => route.params.id as string);
</script>

<style scoped>
.product-detail {
  padding: 20px;
  font-size: 18px;
}
</style>
  • 访问示例
    浏览器地址:http://localhost:5173/product/123
    页面渲染:产品详情,产品 ID:123


可选参数

Vue Router 4 支持可选动态参数,在参数后添加 ? 标记,表示该参数可传可不传,路由同时匹配两种场景。

  • 路由配置示例

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router';
import Product from '../components/Product.vue';

const routes: Array<RouteRecordRaw> = [
  // :id? 代表 id 为可选参数
  {
    path: '/product/:id?',
    name: 'Product',
    component: Product
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;
  • 匹配场景

  1. 无参数:/product

  2. 带参数:/product/456


通配符路由与 404 页面捕获

Vue Router 4 废弃了旧版通配符 *,使用自定义正则匹配捕获所有未定义的路由,用于实现 404 页面。

  • 404 组件 src/components/NotFound.vue

<template>
  <div class="not-found">
    <h1>404 - 页面未找到</h1>
    <p>您访问的路径:{{ fullPath }} 不存在</p>
  </div>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router';
import { computed } from 'vue';

const route = useRoute();
// 获取捕获的完整路径
const fullPath = computed(() => route.fullPath);
</script>

<style scoped>
.not-found {
  text-align: center;
  padding: 40px;
  color: #f56c6c;
}
</style>
  • 路由配置(404 必须放在最后)

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router';
import Product from '../components/Product.vue';
import NotFound from '../components/NotFound.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/product/:id?',
    name: 'Product',
    component: Product
  },
  // 捕获所有未匹配的路由(Vue Router 4 标准写法)
  {
    path: '/:catchAll(.*)',
    name: 'NotFound',
    component: NotFound
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

路由参数解耦

为了降低组件与路由的耦合度,Vue Router 4 支持通过 props 将参数直接注入组件,推荐优先使用

  • 路由配置开启 props

{
  path: '/product/:id',
  name: 'Product',
  component: Product,
  // 开启参数解耦,将 params 转为组件 props
  props: true
}
  • 组件接收 props(无依赖路由 API)

<template>
  <div>产品详情,产品 ID:{{ id }}</div>
</template>

<script setup lang="ts">
// 直接接收路由参数
const props = defineProps<{
  id: string
}>();
</script>

动态参数监听

当路由参数发生变化时(组件复用),需要监听参数更新数据:

<script setup lang="ts">
import { useRoute } from 'vue-router';
import { watch } from 'vue';

const route = useRoute();

// 监听路由参数变化
watch(
  () => route.params.id,
  (newId) => {
    console.log('产品 ID 已更新:', newId);
    // 执行数据刷新逻辑
  }
);
</script>

组合式 API

Vue 3 组合式 API 中,Vue Router 4 提供两个核心函数,用于操作路由。

useRoute

  • 作用:获取当前路由的响应式对象,包含路径、参数、查询参数等信息

  • 使用场景:读取路由参数、获取当前路由信息

import { useRoute } from 'vue-router';
const route = useRoute();

// 常用属性
console.log(route.path);      // 当前路径 /product/123
console.log(route.params);    // 动态参数 { id: '123' }
console.log(route.fullPath);  // 完整 URL 路径

useRouter

  • 作用:获取路由实例,用于编程式导航(手动跳转页面)

  • 使用场景:按钮跳转、表单提交后跳转、路由拦截

import { useRouter } from 'vue-router';

const router = useRouter();

// 编程式导航(推荐命名路由)
function goToProduct(id: string) {
  router.push({
    name: 'Product',
    params: { id }
  });
}

// 后退一页
router.back();

其他补充

多参数路由

Vue Router 4 支持同时定义多个动态参数,适配复杂场景:

// 配置
{ path: '/product/:category/:id', name: 'ProductDetail' }
// 访问 /product/phone/123
// route.params = { category: 'phone', id: '123' }

路由匹配优先级

路由按照定义顺序匹配,越靠前的规则优先级越高;
动态路由优先级高于通配符路由,404 路由必须放在配置最后