好记性不如烂笔头,记录最近遇到的一个Select
组件多隐藏属性模糊查询的需求,以及踩的一个微坑。
1. 实现简单的模糊查询
如果只是对Select
组件Option
的lable/value
做模糊查询的话, 文档或者其他文章都讲过,可以使用下面的查询
<a-select
v-model="search_obj.advertiser"
style="width: 240px;"
mode="multiple"
:maxTagCount="1"
:allowClear="true"
:filterOption="filterOption"
>
<a-select-option value="">
全部
</a-select-option>
<a-select-option v-for="(value, key) in show_advertiser_map" :value="value.advertiser_id">
{{value.alias}}
</a-select-option>
</a-select>
filterOption(input, option) {
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
);
},
如下图所示:可以对option.componentOptions.children[0].text
或者option.componentOptions.propsData.value
做过滤,就能实现模糊查询的效果
2.实现隐藏属性的模糊查询
2.1正确思路:自定义attrs
属性
<a-select-option
v-for="(value, key) in show_advertiser_map"
:value="value.advertiser_id"
:user_name="value.user_name"
>
{{value.alias}}
</a-select-option>
往a-select-option
标签增加了一个user_name
的属性
如图,就把问题转化为了情形1
,使用filterOption
函数过滤选项就好了,但是如果有很多个属性需要过滤呢?岂不是要添加很多个attrs
属性,于是我尝试了更改思路
2.2 微坑思路:动态更改option
数组show_advertiser_map
option
是使用数组循环渲染出来的,那么监听input
的变化,动态调整数组不就好了么?
<a-select
v-model="search_obj.advertiser"
style="width: 240px;"
mode="multiple"
:maxTagCount="1"
:allowClear="true"
@search="filterAdvertiser"
>
<a-select-option value="">
全部
</a-select-option>
<a-select-option v-for="(value, key) in show_advertiser_map" :value="value.advertiser_id">
{{value.alias}}
</a-select-option>
</a-select>
if (val == '') {
this.show_advertiser_map = this.advertiser_map[this.search_obj.game]
return;
}
let arr = [];
this.advertiser_map[this.search_obj.game].forEach((v) => {
if (v.alias.indexOf(val) > -1
|| v.advertiser_id.indexOf(val) > -1
|| v.advertiser_name.indexOf(val) > -1
|| v.company_name.indexOf(val) > -1
|| v.platform == val
|| v.user_name.indexOf(val) > -1
) {
arr.push(v)
}
})
this.show_advertiser_map = arr
console.log(this.show_advertiser_map)
我打印了最终原数组的值,发现是符合预期的,但是实际上select
组件选项却依旧是对vlaue
做了过滤,导致渲染出来的结果是不符合预期的。可是文档里面写的是filterOption
接收bool/function
,默认值是true
,于是我尝试增加:
:filterOption="true"
依旧对vlaue
做了过滤
再次尝试增加:
:filterOption="() => { return true; }"
符合预期!Done!
然后我尝试看Select
组件对应的代码:
filterOption: _vueTypes2['default'].oneOfType([_vueTypes2['default'].bool, _vueTypes2['default'].func]),
确实是接受bool/function
var filterFn = this.$props.filterOption;
if ((0, _propsUtil.hasProp)(this, 'filterOption')) {
if (filterFn === true) {
filterFn = defaultFilter.bind(this);
}
} else {
filterFn = defaultFilter.bind(this);
}
但是当是true
,却有一个defaultFilter
,ok, 离真相越来越近了,继续看defaultFilter
是啥
export function defaultFilterFn(input, child) {
var props = getPropsData(child);
if (props.disabled) {
return false;
}
var value = getPropValue(child, this.optionFilterProp);
if (value.length && value[0].text) {
value = value[0].text;
} else {
value = String(value);
}
return value.toLowerCase().indexOf(input.toLowerCase()) > -1;
}
哦豁,是对value
进行过滤,怪不得
3.总结
- 不指定
filterOption
, 是对选项的value
进行过滤;- 普通指定
filterOption
, 可以对选项的lable/value
进行过滤;- 直接动态调整
Array
, 需要指定filterOption
返回恒真
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。