一、Vue3 Router 传参有哪几种核心方式?
不少刚开始折腾Vue3项目的同学,一碰到页面跳转传参就发懵:到底有多少种传参方式?不同场景选哪种更稳?参数刷新没了咋救?这篇用问答形式,把Vue3 Router传参的关键知识点、实操技巧和避坑点全唠明白,从基础到细节一次吃透~
Vue3 Router 传参方式主要围绕「路由配置」和「跳转时的参数携带」展开,常见的有这四类:
动态路由参数(路径参数)
把参数直接嵌在路由路径里,/user/:id 这种格式,配置路由时用 :参数名 占坑,跳转时把具体值填进去, url 里就会显示成 /user/123 。
params 传参(命名路由的隐式参数)
通过命名路由的 params 字段传参,但只有和动态路由参数匹配的部分才会显式出现在 url;如果路由没配置对应路径参数,这些 params 属于“内存级”参数,刷新页面会丢失。
query 传参(查询参数)
参数跟在 url 的 后面,像 /user?tab=info&page=2 这样,不管路由咋配置,只要跳转时带 query ,参数就会明文出现在 url 里,刷新也不会丢。
props 传参(路由组件解耦方案)
通过路由配置的 props 选项,把路由参数“转成”组件的 props 传入,组件不用直接依赖 useRoute() ,更方便复用和测试。
动态路由参数咋用?适合啥场景?
动态路由参数是“把参数写进 url 路径”的玩法,步骤分两步:配置路由 + 跳转传参 + 接收参数。
配置路由(占坑)
在路由规则里,用 :参数名 定义动态段,
const routes = [
{
path: '/user/:id', // id 是动态参数
name: 'User',
component: () => import('./views/User.vue')
}
]
跳转时传参(填坑)
可以用编程式导航或者声明式导航:
- 编程式(用
router.push):import { useRouter } from 'vue-router' const router = useRouter() router.push({ name: 'User', params: { id: 123 } }) // 或者直接拼路径:router.push('/user/123') - 声明式(用
<RouterLink>):<RouterLink :to="{ name: 'User', params: { id: 123 } }">去用户页</RouterLink> <!-- 或者 <RouterLink to="/user/123">去用户页</RouterLink> -->
组件内接收参数
用 useRoute() 钩子拿参数:
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const userId = route.params.id // 这里的 id 和路由配置里 :id 对应
</script>
适合啥场景?
- 页面唯一性强:比如用户详情、商品详情,每个
id对应唯一页面, url 里带id也方便用户收藏/分享。 - SEO 需求:搜索引擎更易抓取带参数的静态路径(
/user/123比?id=123更像静态页)。
query 传参和 params 传参有啥区别?
很多同学分不清这俩,核心差异在「参数是否显式在 url」和「刷新是否保留」上,具体看这张对比表:
| 维度 | query 传参 | params 传参(非动态路由场景) |
|---|---|---|
| url 显示 | 明文显示在 后(如 ?tab=info) |
不在 url 显示(仅内存中临时保存) |
| 刷新保留 | 刷新后参数还在 | 刷新后参数丢失(因为没存在 url 里) |
| 路由配置依赖 | 不需要路由配置提前占坑 | 若想参数显式在 url,必须配动态路由 |
| 使用灵活性 | 适合临时筛选、分页等可变参数 | 适合和动态路由绑定的“页面核心标识” |
举个栗子🌰
做电商商品列表,筛选条件(比如价格区间、分类)适合用 query :因为用户刷新页面后,筛选条件得保留,而且不需要“收藏筛选后的 url”时,用 query 灵活;
做订单详情页,订单 id 是页面核心标识,适合用动态路由参数(属于 params 里和路径绑定的部分),保证 url 里有 id ,刷新也能拿到。
用 props 咋给路由组件传参?
路由组件直接用 `useRoute()` 拿参数,会让组件和路由强耦合(比如复用组件时,得先配路由),用 `props` 传参能解耦,让组件更“纯粹”。
路由配置里开 props: true
当路由是动态路由(如 /user/:id ),把 props 设为 true ,路由的 params 会自动变成组件的 props:
路由配置:
{
path: '/user/:id',
name: 'User',
component: User,
props: true // 关键配置
}
组件里接收:
<script setup> defineProps(['id']) // 直接用 props 接收,不用 useRoute 了 console.log(id) // 能拿到路由里的 :id 参数 </script>
传静态 props(少用,但得知道)
props 设为对象,不管路由参数是啥,组件都拿静态值:
{
path: '/user',
component: User,
props: { tab: 'info' } // 组件拿到的 tab 固定是 'info'
}
函数式 props(动态逻辑传参)
props 可以是函数,根据 route 对象返回动态值,适合复杂场景:
{
path: '/user/:id',
component: User,
props: (route) => {
return {
id: route.params.id,
defaultTab: 'info' // 额外加静态值
}
}
}
组件接收:
<script setup> defineProps(['id', 'defaultTab']) </script>
为啥推荐用 props?
- 解耦路由依赖:组件不用关心“我是不是路由组件”,复用的时候直接传 props 就行。
- 测试更简单:写单元测试时,不用模拟路由,直接传 props 就能测。
编程式导航和声明式导航传参有啥不同?
Vue3 里跳转页面分「编程式(用 JS 逻辑跳)」和「声明式(用
编程式导航(router.push / router.replace 等)
适合有逻辑判断后再跳转的场景,比如点击按钮后,先调接口存数据,再跳页面:
import { useRouter } from 'vue-router'
const router = useRouter()
const handleClick = async () => {
await saveData() // 调接口存数据
router.push({
name: 'Success',
query: { msg: '保存成功' }
})
}
声明式导航(
适合页面上的静态链接,比如导航栏、菜单:
<RouterLink
:to="{
name: 'Article',
params: { id: 456 },
query: { from: 'home' }
}"
>
看文章
</RouterLink>
核心区别
- 编程式是逻辑里的动态跳转,能结合异步操作、条件判断;
- 声明式是模板里的静态跳转,更直观,适合用户能直接点的链接。
传参后刷新页面,参数丢了咋解决?
碰到“跳转时参数有值,刷新页面就没了”,十有八九是「params 传参没和动态路由绑定」导致的。
问题根源
如果用 params 传参,但路由没配置对应的动态路径参数,这些 params 只存在内存里,刷新页面时,路由重新初始化,内存里的参数就没了。
比如错误示范:
路由配置是 path: '/user' (没配 :id ),但跳转时传 params: { id: 123 } ,id 不会出现在 url ,刷新就丢。
解决方法
根据需求选方案:
-
需要参数刷新保留 → 用 query 传参
把参数放到query里,不管路由咋配,query会明文存在 url ,刷新不丢:router.push({ name: 'User', query: { id: 123 } }) // url 变成 /user?id=123 ,刷新后 route.query.id 还在 -
参数是页面核心标识 → 用动态路由参数
把参数写到路由路径里(配:id),这样参数既在 url 里,刷新也能拿到:// 路由配置 { path: '/user/:id', ... } // 跳转 router.push({ name: 'User', params: { id: 123 } }) // url 是 /user/123 ,刷新后 route.params.id 还在 -
临时参数,刷新丢了也没事 → 继续用 params(但得接受刷新丢失)
如果参数是临时用的(比如表单跳转前的临时状态),丢了也不影响,那继续用params传参就行,不用改。
多参数传递时,怎么组织更清晰?
页面跳转时,经常要传多个参数(id、类型、筛选条件),乱传容易搞混,得按“参数重要性 + 场景”分类传。
分类传参逻辑
- 核心标识参数(如用户 id、商品 id):用动态路由参数,写进 url 路径,保证刷新不丢,且页面唯一性强。
- 可变筛选参数(如分页、tab 切换、搜索关键词):用query 传参,明文在 url ,刷新保留,还能让用户通过 url 分享筛选状态。
- 临时逻辑参数(如是否弹窗、临时标记):用params 传参(非动态路由场景),但要接受刷新丢失。
举个综合栗子🌰
做一个“商品详情 + 评论 tab + 分页”的页面:
- 商品
id是核心 → 动态路由:path: '/product/:id' - tab(是看详情还是评论)、分页
page→ query 传参:query: { tab: 'comment', page: 2 } - 临时标记(比如是否自动展开评论)→ params 传参(非动态路由,刷新丢了也没事)
跳转代码:
router.push({
name: 'Product',
params: { id: 789 }, // 动态路由参数
query: { tab: 'comment', page: 2 }, // 筛选参数
params: { autoOpen: true } // 临时参数(注意:这里如果路由没配 :autoOpen,刷新会丢)
})
这样分类后,参数用途清晰,维护起来也方便~
Vue3 组合式 API 里,咋获取路由参数?
Vue3 的 <script setup> 语法里,获取路由参数得用 `useRoute()` 钩子,步骤很简单:
导入并调用 useRoute
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute() // 拿到当前路由对象
</script>
取 params 或 query
- 取动态路由参数 / params :
route.params.参数名 - 取 query 参数:
route.query.参数名
示例(承接动态路由例子):
<template>
<div>用户ID:{{ userId }}</div>
<div>当前标签:{{ activeTab }}</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const userId = route.params.id // 动态路由参数
const activeTab = route.query.tab // query 参数
</script>
注意点
useRoute() 必须在组合式 API 上下文里用(<script setup> 或 setup() 函数里),不能在普通函数、生命周期钩子外乱用,否则拿不到路由对象~
传参时容易踩的坑,咋避?
最后聊聊踩坑经验,提前避坑少掉头发~
坑1:params 传参没配动态路由,刷新丢参数
→ 解决:核心参数用动态路由或 query;临时参数接受丢失,或者转成 query。
坑2:路由配置了动态参数,但跳转时没传,页面崩了
→ 解决:跳转前做参数校验,或者路由配置里给动态参数设默认(path: '/user/:id?' 加问号表示可选)。
坑3:用了 props: true ,但组件没定义对应 props
→ 解决:组件里用 defineProps 声明接收的参数,defineProps(['id']) 。
坑4:编程式导航用 path 跳转时,传 params 不生效
→ 原因:用 path 跳转时,params 会被忽略(因为 path 是静态字符串,没法绑定 params)。
→ 解决:要么用 name + params 跳转,要么把参数拼到 path 里(如 /user/123 )。
把这些传参方式、场景、避坑点理清楚后,Vue3 页面跳转传参就不再是玄学啦~下次写项目时,先想清楚参数的“重要性”和“是否要刷新保留”,再选对应的传参方式,代码逻辑会清爽很多~如果还有细节没搞懂,评论区随时喊我~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网


发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。