将 props 传递给路由组件 | Vue Router
为什么需要传递 props?
在 Vue Router 中,直接在组件中使用 $route 或 useRoute() 会导致组件与路由紧密耦合,限制了组件的灵活性和可复用性。通过 props 配置,我们可以让组件更加独立和可测试。
基本用法
原始方式(不推荐)
vue
<!-- User.vue -->
<template>
<div>
用户 {{ $route.params.id }}
</div>
</template>javascript
const routes = [
{ path: '/users/:id', component: User }
]使用 Props 方式(推荐)
vue
<!-- User.vue -->
<script setup>
defineProps({
id: String
})
</script>
<template>
<div>
用户 {{ id }}
</div>
</template>javascript
const routes = [
{ path: '/user/:id', component: User, props: true }
]三种 Props 模式
1. 布尔模式
当 props: true 时,路由参数会自动作为 props 传递给组件:
javascript
const routes = [
{ path: '/user/:id', component: User, props: true }
]2. 对象模式
当需要传递静态 props 时使用:
javascript
const routes = [
{
path: '/promotion/from-newsletter',
component: Promotion,
props: { newsletterPopup: false }
}
]3. 函数模式
最灵活的方式,允许你进行数据转换和组合:
javascript
const routes = [
{
path: '/search',
component: SearchUser,
props: route => ({
query: route.query.q,
timestamp: Date.now()
})
}
]🔍 示例:访问
/search?q=vue会传递{query: 'vue', timestamp: 1642425600000}给组件
命名视图的 Props 配置
对于有多个命名视图的路由,需要为每个视图单独配置 props:
javascript
const routes = [
{
path: '/user/:id',
components: {
default: User,
sidebar: Sidebar
},
props: {
default: true, // 将 params.id 传递给 User 组件
sidebar: false // 不传递任何 props 给 Sidebar
}
}
]通过 RouterView 插槽传递
虽然不常用,但也可以通过 <RouterView> 插槽传递 props:
html
<RouterView v-slot="{ Component }">
<component
:is="Component"
custom-prop="自定义值"
/>
</RouterView>⚠️ 注意:这种方式会让所有路由组件都接收到相同的 props,通常不推荐使用。
最佳实践
1. 保持组件独立性
vue
<!-- Good: 组件不依赖路由 -->
<script setup>
defineProps({ id: String })
</script>
<!-- Avoid: 组件与路由耦合 -->
<script setup>
const route = useRoute()
const id = route.params.id
</script>2. 使用函数模式进行数据转换
javascript
// 将字符串参数转换为数字
props: route => ({
userId: parseInt(route.params.id),
page: parseInt(route.query.page) || 1
})3. 保持 Props 函数无状态
javascript
// Good: 无状态函数
props: route => ({ query: route.query.q })
// Avoid: 有状态操作
props: route => ({
query: route.query.q,
// 这会导致问题,因为函数只在路由变化时执行
randomValue: Math.random()
})实际应用场景
用户详情页
javascript
{
path: '/users/:userId',
component: UserProfile,
props: route => ({
userId: parseInt(route.params.userId),
tab: route.query.tab || 'overview'
})
}搜索页面
javascript
{
path: '/search',
component: SearchResults,
props: route => ({
query: route.query.q,
filters: {
category: route.query.category,
sort: route.query.sort || 'relevance'
}
})
}🎯 总结:使用 props 配置可以让你的组件更加灵活、可测试和可复用,是构建高质量 Vue 应用的重要技巧。