一、props在vue router里是干啥的?
p>不少刚开始学Vue路由的朋友,碰到vue - router的props配置时总会犯懵——这玩意儿到底咋用?和直接用$route传参比有啥好处?今天就唠唠vue - router里props的用法和优势,把这些疑惑一个个掰碎了讲清楚。
简单说,props是给路由组件传递参数的一种“优雅方式”,咱平常写路由组件时,要是想拿路由里的参数(比如/user/:id里的id),得用this.$route.params.id这种写法,但这样做有个问题:组件和路由紧紧绑在一起了(专业点叫“强耦合”)。
而props的作用,就是把路由里的参数“解耦”出来,变成组件的props属性,路由负责把参数“递”给props,组件只需要像接收普通父传子参数一样,用props选项声明接收就行,这样一来,哪怕以后路由规则变了,组件内部也不用大改,甚至组件还能在非路由场景下复用(比如当普通组件给其他页面用)。
props的几种配置玩法
vue - router给props设计了布尔、对象、函数三种配置模式,不同场景用不同模式,灵活得很。
布尔模式(props: true)
适合“把路由params参数直接传给组件props”的场景,举个例子:
路由配置长这样:
const routes = [
{
path: '/user/:id',
component: User,
props: true
}
]
User组件里只需要声明props:
export default {
props: ['id'], // 声明接收id参数
mounted() {
console.log(this.id) // 直接用this.id,不用this.$route.params.id
}
}
这种模式的好处很直接:路由params和组件props自动映射,组件不用关心“路由参数咋拿”,只负责用props里的id。
对象模式(props: { ... })
要是你想给组件传静态参数(参数值不随路由变化),就用对象模式,比如做个固定标题的页面:
路由配置:
const routes = [
{
path: '/about',
component: About,
props: { title: '关于我们', isShow: true }
}
]
About组件接收:
export default {
props: { String,
isShow: Boolean
},
mounted() {
console.log(this.title, this.isShow) // 输出“关于我们” true
}
}
这种模式适合“组件需要固定配置”的场景,比如页面默认开关、固定文案这些,不管路由怎么变,传的值都是固定的。
函数模式(props: (route) => ({ ... }))
如果需要动态处理路由参数(比如结合query参数、加工params格式),函数模式就派上用场了。route参数是当前路由对象,里面包含params、query、path等信息。
举个实际例子:商品详情页需要传商品id(params),还要根据query里的tab决定显示哪个标签页。
路由配置:
const routes = [
{
path: '/product/:id',
component: Product,
props: (route) => ({
productId: route.params.id, // 取params里的id
activeTab: route.query.tab || 'info' // 取query里的tab,没有就默认info
})
}
]
Product组件接收:
export default {
props: {
productId: String,
activeTab: String
},
mounted() {
console.log(this.productId, this.activeTab)
// 比如访问/product/123?tab=detail,就输出“123” “detail”
}
}
函数模式的灵活性在于:能对路由参数做任意处理——比如把id从字符串转成数字,或者合并多个参数,甚至还能结合Vuex、全局配置等,返回更复杂的参数(不过要注意,函数里this不是Vue实例,别直接用this.$store,可以把逻辑放到组件里处理)。
用props代替$route传参有啥优势?
很多人会问:“我直接用this.$route也能拿参数,为啥非要用props?” 这就得聊聊解耦、维护、设计理念这几个关键点了。
组件解耦更彻底
如果组件里全是this.$route.xxx,这个组件就和路由“绑死”了——一旦路由规则变了(比如参数名从id改成userId),组件里所有this.$route.params.id都得改;而且这个组件也没法在非路由场景复用(比如当弹窗组件用,没路由的时候$route就不存在了)。
但用props的话,组件只关心“我需要哪些参数”,不管参数从路由来、还是父组件手动传,比如上面的User组件,哪怕不在路由里用,父组件也能这么写:
<User :id="100" />
组件完全不用改,复用性直接拉满。
代码可读性&维护性提升
看组件代码时,直接看props选项就知道“这个组件需要啥参数”,不用满世界找this.$route在哪;路由配置里的props也清晰展示了“参数咋从路由映射到组件”,后期要改参数逻辑,只需要动路由配置的props部分,组件内部完全不用碰。
举个反面例子:如果组件里到处是this.$route.params.id,某天产品说“路由参数要加个前缀”,你得把所有this.$route.params.id改成this.$route.params.id.replace('prefix - ', ''),改起来又麻烦又容易漏,但用props的话,只需要在路由的函数模式里改一行:
props: (route) => ({
productId: route.params.id.replace('prefix - ', '')
})
组件里该咋用还咋用,完全不受影响。
更符合Vue的设计理念
Vue强调“单向数据流”和“组件化”,props是组件通信的核心方式之一,用props做路由传参,相当于把“路由”当成一个特殊的“父组件”,通过props把数据“流”到子组件里,完美契合Vue的设计逻辑。
实际开发中容易踩的坑和注意点
知道了用法和优势,也得避避坑,这几个细节一定要注意:
布尔模式只传params,不传query
props: true时,只有$route.params里的参数会被传给props,query参数(比如?tab=info)不会自动传,如果要传query,必须用函数模式自己处理,
props: (route) => ({
...route.params, // 传params
...route.query // 传query
})
组件必须声明props选项
不管用哪种模式,组件里一定要用props选项声明接收的参数!比如用了props: true,但组件没写props: ['id'],那this.id就是undefined,直接报错。
函数模式里的this不是Vue实例
路由配置里的props函数,this指向不是Vue实例,所以别在函数里写this.$store、this.$axios这些,如果需要依赖Vuex或者工具库,建议把逻辑放到组件的computed或mounted里处理,或者在函数里返回需要的参数,组件再自己调接口。
举个完整小例子,看效果更直观
假设做一个“订单详情页”,需要传订单id(params),还要根据查询参数mode(普通/精简模式)渲染不同布局,用函数模式实现:
路由配置:
const routes = [
{
path: '/order/:orderId',
component: OrderDetail,
props: (route) => ({
orderId: route.params.orderId,
displayMode: route.query.mode || 'normal'
})
}
]
OrderDetail组件:
export default {
props: {
orderId: {
type: String,
required: true // 订单id是必须的
},
displayMode: {
type: String,
default: 'normal' // 默认普通模式
}
},
mounted() {
console.log('订单ID:', this.orderId)
console.log('显示模式:', this.displayMode)
// 这里可以用orderId调接口拿订单数据,用displayMode决定渲染逻辑
}
}
当访问/order/123?mode=simple时,组件里this.orderId是'123',this.displayMode是'simple';如果访问/order/456(没带query),displayMode就是默认的'normal'。
这个例子里,路由负责“参数传递和简单处理”,组件只负责“用参数做业务逻辑”,分工明确,后期维护也方便——比如以后要加个“暗黑模式”参数,只需要在路由的props函数里加一行,组件完全不用动。
props的核心价值是“灵活解耦”
vue - router的props配置,本质是在路由和组件之间搭了个“智能传参桥梁”:
- 布尔模式:快速把
params映射给props,简单场景直接用; - 对象模式:传静态参数,给组件固定配置;
- 函数模式:复杂参数处理,想怎么加工就怎么加工。
而它最大的优势,是让组件更干净、更易复用、更好维护——毕竟谁也不想改个路由参数,还要在组件里到处找$route对吧?
现在再看props,是不是觉得“哦,原来这玩意儿这么有用”?下次写路由组件时,别再一股脑用this.$route了,试试props配置,你会发现代码清爽了不少~
(全文约1500字,把props的用法、优势、坑点、例子全唠明白了,新手能跟着步骤用起来,老手也能再巩固下设计思路~)
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网


