在 Vue Router 中,"传递多个参数" 通常分为两种情况:路径参数(Params) 和 查询参数(Query)。它们的展示方式和获取方式完全不同。
场景一:路径参数(Params)------ URL 中的必填段
适用于必须携带 的信息,比如 /user/123/post/456(用户ID和文章ID)。
1. 路由配置(定义多个占位符)
javascript
const routes = [
{
path: '/user/:userId/post/:postId', // 定义两个参数
name: 'PostDetail',
component: PostDetail
}
]
2. 如何传递(跳转时)
javascript
// 方式 A: 使用 name + params
router.push({ name: 'PostDetail', params: { userId: '123', postId: '456' } })
// 方式 B: 直接拼接路径
router.push(`/user/123/post/456`)
3. 页面中如何展示(获取数据)
推荐写法(使用 props 解耦,最优雅) :
在路由配置中开启 props: true,参数会自动变为组件的 props。
javascript
// router/index.js
const routes = [
{ path: '/user/:userId/post/:postId', component: PostDetail, props: true }
]
// PostDetail.vue
<script setup>
// 直接通过 props 接收,无需操作 route 对象
const props = defineProps(['userId', 'postId'])
// 直接拿去展示或请求接口
console.log(props.userId, props.postId)
</script>
<template>
<div>
<h1>用户 ID:{{ userId }}</h1>
<h2>文章 ID:{{ postId }}</h2>
</div>
</template>
传统写法(使用 useRoute) :
如果不想用 props,可以在组件内通过 $route.params 获取。
vue
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 展示时直接使用 route.params.userId 和 route.params.postId
</script>
<template>
<p>参数对象:{{ route.params }}</p> <!-- 输出 { "userId": "123", "postId": "456" } -->
</template>
场景二:查询参数(Query)------ URL 中的可选键值对
适用于筛选、分页、搜索关键词 等可选信息,比如 /search?keyword=vue&page=1&sort=asc。
1. 路由配置(无需占位符)
javascript
const routes = [
{ path: '/search', component: SearchResult } // 不需要 :param
]
2. 如何传递(跳转时)
javascript
// 使用 query 字段
router.push({ path: '/search', query: { keyword: 'vue', page: '1', sort: 'asc' } })
// 最终 URL 变为 /search?keyword=vue&page=1&sort=asc
3. 页面中如何展示(获取数据)
通过 route.query 获取一个包含所有参数的对象。
vue
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 直接展示
const searchKeyword = route.query.keyword
const currentPage = route.query.page
</script>
<template>
<div>
<p>当前搜索词:{{ route.query.keyword || '无' }}</p>
<p>当前页码:{{ route.query.page }}</p>
<p>排序方式:{{ route.query.sort }}</p>
<!-- 直接打印整个对象方便调试 -->
<pre>完整参数:{{ route.query }}</pre>
</div>
</template>
场景三:混合使用(路径参数 + 查询参数)
实际业务中经常混用,例如:查看某用户某文章的第 N 页评论。
URL:/user/123/post/456?page=2&size=10
vue
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 路径参数(必填)
const userId = route.params.userId
const postId = route.params.postId
// 查询参数(选填)
const page = route.query.page || 1
const size = route.query.size || 10
</script>
<template>
<h3>用户 {{ userId }} 的文章 {{ postId }}</h3>
<p>当前查看第 {{ page }} 页,每页 {{ size }} 条</p>
</template>
4. 关键注意点(避免展示错乱)
| 场景 | 注意事项 | 解决方案 |
|---|---|---|
| 相同组件,参数变化 | 从 /user/1/post/2 跳转到 /user/3/post/4 时,组件实例会被复用 ,created 或 setup 不会重新执行,页面数据可能不刷新。 |
必须监听路由变化 : watch(() => route.params, (newParams) => { /* 重新请求数据 */ }, { deep: true }) |
| 刷新页面丢失数据 | 刷新页面时,路径参数(Params) 依然在 URL 中,可以正常获取;但如果是通过 push 传递 params 且未写在路径中(动态隐藏参数),刷新会丢失。 |
强制要求 :所有 params 参数必须在 path 中定义占位符(如 :userId),否则无法持久化。 |
| Query 参数的类型 | URL 中的 Query 参数默认都是 字符串 (?page=1 取出来是 "1")。 |
展示时如需数字运算,记得用 Number(route.query.page) 或 parseInt。 |