Vue3 路由跳转传值方法
了解 Vue 3 中路由跳转时传值的方法是开发中的常见需求。由于 Vue 3 引入了 Composition API,路由的使用方式与 Vue 2 有所不同。下面我将为你梳理几种主要的路由传值方式。
下面是一个汇总表格,帮助你快速了解各种传值方式的特点:
传值方式 | 特点 | 适用场景 | 页面刷新后数据是否保留 |
---|---|---|---|
动态路由参数 (Params) | 参数是 URL 的一部分 (如 /user/123 ) |
传递必要标识符,如用户ID、文章ID等 | 是 |
查询参数 (Query) | 参数以键值对形式附在 URL 后 (如 ?name=John&age=30 ) |
传递可选或过滤参数,如搜索关键字、分页信息、筛选条件 | 是 |
路由状态 (State) | 参数不会暴露在 URL 中,通过路由对象的 state 属性传递 |
传递敏感或临时数据,如表单数据、大量数据 | 否 |
Props 解耦 | 将路由参数作为组件的 Props 传入,而非在组件内直接依赖 $route |
提高组件的可复用性和可测试性,减少与路由的耦合 | 同 Params/Query |
🧭 路由传值操作步骤
在 Vue 3 中,路由跳转传参通常遵循以下步骤:
- 引入 API:在需要跳转的组件中,引入
useRouter
。 - 执行跳转:调用
router.push
等方法进行跳转,并传入参数。 - 接收参数:在目标组件中,引入
useRoute
,并通过route
对象获取传递过来的参数。
🔧 具体使用方式
1. 动态路由参数 (Params)
动态路由参数是 URL 的一部分,适合传递像用户 ID、文章编号这类标识符。
- 定义路由:在路由配置中使用冒号
:
指定动态参数。// router/index.js import { createRouter, createWebHistory } from 'vue-router'; const routes = [ // ... 其他路由 { path: '/user/:id', // 定义动态路由参数 id name: 'UserDetail', component: UserDetail } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router;
- 传递参数:使用
router.push
并指定params
。<script setup> import { useRouter } from 'vue-router'; const router = useRouter(); const gotoUserDetail = (userId) => { router.push({ name: 'UserDetail', // 使用命名的路由,传递 params 时必须用 name params: { id: userId } // 传递参数,键需与路由定义中的动态段匹配 }); // 或者 router.push(`/user/${userId}`); // 直接写 path }; </script>
- 接收参数:在目标组件中使用
useRoute
获取params
。
注意:如果提供了<script setup> import { useRoute } from 'vue-router'; const route = useRoute(); // 获取动态路由参数 const userId = route.params.id; // 例如,URL 是 /user/123, 则 userId 为 '123' </script>
path
,params
会被忽略,此时需要提供路由的name
或手写完整的带有参数的path
。
2. 查询参数 (Query)
查询参数以键值对的形式附加在 URL 末尾(?key=value
),适合传递可选参数或过滤条件。
- 传递参数:使用
router.push
并指定query
。
跳转后 URL 会变为类似<script setup> import { useRouter } from 'vue-router'; const router = useRouter(); const gotoUserList = (pageNum, filters) => { router.push({ path: '/users', query: { page: pageNum, sort: filters.sortBy } // 传递查询参数 }); // 或使用 name: router.push({ name: 'UserList', query: { ... } }); }; </script>
/users?page=2&sort=name
的形式。 - 接收参数:在目标组件中使用
useRoute
获取query
。<script setup> import { useRoute } from 'vue-router'; const route = useRoute(); // 获取查询参数 const currentPage = route.query.page; const sortType = route.query.sort; </script>
3. 路由状态 (State)
Vue Router 允许在跳转时通过 state
传递一些不会显示在 URL 中的临时数据。
- 传递参数:使用
router.push
并指定state
。<script setup> import { useRouter } from 'vue-router'; const router = useRouter(); const gotoResult = (formData) => { router.push({ name: 'ResultPage', state: { submittedData: formData // 通过 state 传递数据 } }); }; </script>
- 接收参数:在目标组件中通过
router.currentRoute.value.state
获取。
注意:通过<script setup> import { useRouter } from 'vue-router'; const router = useRouter(); // 获取通过 state 传递的参数 const submittedData = router.currentRoute.value.state?.submittedData; </script>
state
传递的数据不会在页面刷新后保留,且不会暴露在 URL 中,适合敏感或临时数据。
4. 使用 Props 解耦
可以将路由参数作为 Props 传递给组件,从而减少组件与 $route
的直接耦合,提高组件的可复用性和可测试性。
- 配置路由:在路由配置中设置
props: true
(对于动态路由参数)或使用函数形式(更灵活)。// router/index.js { path: '/user/:id', name: 'UserDetail', component: UserDetail, props: true // 开启 props 传参,route.params 将设置为组件的 props // 或者使用函数形式更灵活地返回 props 对象 // props: (route) => ({ id: route.params.id, query: route.query.search }) }
- 接收参数:在目标组件中像接收普通 props 一样使用。
<script setup> defineProps({ id: { type: String, required: true } }); </script>
⚠️ 注意事项与技巧
-
Params 与 Query 的区别:
params
是 URL 的一部分,通常用于标识唯一资源。如果路由定义了params
但跳转时未提供,可能会导致导航失败。query
是查询字符串,可选参数。更适合过滤、分页等场景。
-
响应参数变化:当同一个组件仅因参数(如从
/user/1
到/user/2
)不同而重新渲染时,组件的mounted
等生命周期钩子不会再次执行。为了响应参数变化,你可以:- 使用
watch
监听route
对象上的params
或query
。
<script setup> import { watch } from 'vue'; import { useRoute } from 'vue-router'; const route = useRoute(); watch(() => route.params.id, (newId) => { // 当 id 变化时,执行数据获取等操作 fetchUserData(newId); }); </script>
- 或者使用
onBeforeRouteUpdate
导航守卫(需引入vue-router
)。
- 使用
-
何时使用其他状态管理:对于复杂的应用状态共享(如用户登录信息、全局主题),或需要跨多个非父子关系组件共享的数据,使用 Pinia (Vue 3 推荐的状态管理库) 或 Vuex 通常是比路由传参更好的选择。
💡 如何选择传值方式
选择哪种方式取决于你的具体需求:
-
需要在URL中体现参数,并且刷新页面后参数不丢失?
- 是:使用 Params (用于必要标识符) 或 Query (用于过滤、分页等选项)。
- 否:考虑使用 State(用于敏感数据、临时数据或大数据量)。
-
希望组件能更方便地复用和测试,减少对路由的依赖?
- 是:在路由配置中开启 Props 传参。