在 Vue 开发中,经常会遇到这样的需求:
某个属性满足条件时才传给组件,否则完全不传,而不是传
undefined。
例如 Element UI 的 el-select:
<el-select
:filter-method="filterMethodFunc"
/>希望实现:
满足条件:传入
filter-method不满足条件:组件完全没有
filter-method这个 Prop
为什么不推荐使用三目返回 undefined
很多人的第一反应可能是:
<el-select
:filter-method="condition ? filterMethodFunc : undefined"
/>虽然很多组件能够正常工作,但是实际上:
Prop 仍然会传递给组件
只是值变成了
undefined某些组件会根据 Prop 是否存在来决定逻辑,而不仅仅是判断值
因此,更推荐真正做到「有则传,没有则不传」。
推荐方案:使用 v-bind 动态对象
Vue 的 v-bind 可以直接绑定一个对象:
<el-select
v-bind="
condition
? { 'filter-method': filterMethodFunc }
: {}
"
/>condition 为 true
最终等价于:
<el-select
:filter-method="filterMethodFunc"
/>condition 为 false
最终等价于:
<el-select />这样才是真正意义上的不传该属性。
实际业务案例
最近项目中遇到了一个需求:
组件支持两种搜索方式:
① 默认搜索
如果传入了 filterMethodField
例如:
<CustomSelect
filter-method-field="customerName"
/>说明使用组件内置的搜索逻辑。
也就是:
defaultFilterMethodFunc② 自定义搜索
如果没有传 filterMethodField
但是传入了:
<CustomSelect
:filter-method-func="myFilter"
/>那么就使用外部传入的方法:
myFilter最终写法
<el-select
v-bind="
filterMethodField || filterMethodFunc
? {
'filter-method': filterMethodField
? defaultFilterMethodFunc
: filterMethodFunc
}
: {}
"
/>对应关系:
这样可以做到:
有字段 → 自动开启默认搜索
没字段但有外部方法 → 使用自定义搜索
两个都没有 → 不开启搜索
为什么有时候会看到 ...
有时候会看到这样的写法:
v-bind="{
...(condition ? { a: 1 } : {}),
...(condition2 ? { b: 2 } : {})
}"很多人第一次都会疑惑:
为什么多了
...?
其实这是 ES6 对象展开(Object Spread)。
作用就是:
把多个对象合并成一个对象。
例如:
{
...(true ? { a: 1 } : {}),
...(false ? { b: 2 } : {}),
...(true ? { c: 3 } : {})
}最终得到:
{
a: 1,
c: 3
}什么情况下需要 ...
一个条件
不需要。
直接返回对象即可:
v-bind="
condition
? { a: 1 }
: {}
"这是最推荐的写法。
多个条件
如果组件有很多可选属性:
例如:
filter-method
remote-method
visible-change
loading
那么可以写成:
v-bind="{
...(filterMethod
? {
'filter-method': filterMethod
}
: {}),
...(remoteMethod
? {
remote: true,
'remote-method': remoteMethod
}
: {}),
...(visibleChange
? {
'visible-change': visibleChange
}
: {}),
...(loading
? {
loading: true
}
: {})
}"这样每一块逻辑都是独立的:
新增一个功能,只需要新增一个对象
删除一个功能,只需要删除对应对象
不会互相影响
可维护性非常高
总结
推荐原则
✅ 一个条件控制一个属性
v-bind="
condition
? { prop: value }
: {}
"✅ 多个条件控制多个属性
v-bind="{
...(condition1 ? { prop1: value1 } : {}),
...(condition2 ? { prop2: value2 } : {}),
...(condition3 ? { prop3: value3 } : {})
}"优点
真正做到「有则传,没有则不传」
避免传递
undefined模板更加清晰
非常适合封装公共组件
后续扩展方便,可维护性高
一句话总结:
一个条件直接返回对象;多个条件使用对象展开(
...)合并多个对象。