Element中select自定义过滤属性
引言
上篇文章我自己实现了一个“更高效率”的select自定义过滤函数,
后来我又有了另外一个想法:
既然原生option是通过this.visible = new RegExp(escapeRegexpString(query), 'i').test(this.currentLabel) || this.created;
来控制显示隐藏的,那么为什么我不可以把option整个对象传进来,
通过遍历所有属性,最后得到是否显示的boolean呢?
实现
既然要传入item,那么就需要在options.vue中的props定义
item,
props: {
item: Object
}
1
2
3
2
3
然后修改一下queryChange()
queryChange(query) {
let regexp = new RegExp(escapeRegexpString(query), 'i');
let tmpVisible = false;
Object.keys(this.item).forEach(k => {
tmpVisible = tmpVisible || (regexp.test(this.item[k]) || this.created);
});
this.visible = tmpVisible;
// this.visible = new RegExp(escapeRegexpString(query), 'i')
// .test(this.currentLabel) || this.created;
if (!this.visible) {
this.select.filteredOptionsCount--;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
看下代码,首先定义一个正则表达式(其实就是注释部分的正则)和
一个用于暂存的临时变量tmpVisible,通过遍历this.item的所有属性
查找是否匹配query,最后把临时变量赋给this.visible,其他操作和
官方原版一致。
接下来只需要把item传入option即可。
<el-select filterable v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:item="item"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
数据格式如下:
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}, {
value: '选项3',
label: '蚵仔煎'
}, {
value: '选项4',
label: '龙须面'
}, {
value: '选项5',
label: '北京烤鸭'
}]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
效果

更进一步
那么我们再加一个需求,我想自定义哪些属性需要遍历,怎么样?
比如我们有一个员工列表,数据格式如下:
users:[{
name:'张某',
id:'1',
phone:13600000000
},{
name:'王某',
id:'2',
phone:18900000000
},{
name:'李某',
id:'3',
phone:18600000000
}]
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
如果用上面的方法,我们会遍历全部属性,无论用户的输入是匹配了
name还是id或者是phone都会显示。
假设我只需要匹配name和id怎么办呢?
我的想法是传入一个字符串数组,用于标识需要匹配的属性名。
queryChange(query) {
let regexp = new RegExp(escapeRegexpString(query), 'i');
let tmpVisible = false;
this.filterProps.forEach(k=>{
if (this.item[k]) {
tmpVisible = tmpVisible || (regexp.test(this.item[k]) || this.created);
}
});
this.visible = tmpVisible;
if (!this.visible) {
this.select.filteredOptionsCount--;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
其实和上面的逻辑差不多,只是循环的内容不一样了。

再更进一步:如果用户有需求,就遍历用户规定的属性, 否则就默认遍历全部属性。
if (typeof this.filterProps !== 'undefined') {
this.filterProps.forEach(k=>{
if (this.item[k]) {
tmpVisible = tmpVisible || (regexp.test(this.item[k]) || this.created);
}
});
} else {
Object.keys(this.item).forEach(k => {
tmpVisible = tmpVisible || (regexp.test(this.item[k]) || this.created);
});
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
只要加一个if...else判断就可以了。