最近在被安排去做前端开发,由于下拉框中的数据可能太多,滚动一个个翻着来查找影响效率,因此需要实现下拉框带有根据输入进行筛选的功能,由于本项目是用ant design开发的,而antd官网上针对下拉框Select组件也有此功能的实现,具体代码案例如下:
<template>
<a-select
show-search
placeholder="Select a person"
option-filter-prop="children"
style="width: 200px"
:filter-option="filterOption"
@focus="handleFocus"
@blur="handleBlur"
@change="handleChange"
>
<a-select-option value="jack">
Jack
</a-select-option>
<a-select-option value="lucy">
Lucy
</a-select-option>
<a-select-option value="tom">
Tom
</a-select-option>
</a-select>
</template>
<script>
export default {
methods: {
handleChange(value) {
console.log(`selected ${value}`);
},
handleBlur() {
console.log('blur');
},
handleFocus() {
console.log('focus');
},
filterOption(input, option) {
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
);
},
},
};
</script>
以上代码的重点就在于第3、5、7行和第35~39行,第3、5、7行使下拉框支持搜索功能,第35~39行通过filterOption指定一个方法来实现筛选的规则,具体的效果实现也可直接去官网案例去体验下:访问官网案例
虽说官网上有案例,但在我们项目中使用却没有那么顺利,首先我们项目中的原先项目代码如下:
<a-select placeholder="全部" v-model:value="formState.llcsSysType" :getPopupContainer="(triggerNode) => triggerNode.parentNode">
<a-select-option v-model:value="item.roleCode" v-for="(item, index) in roleArr" :key="index">
{{ item.roleName }}
</a-select-option>
</a-select>
当我参考官网案例直接在a-select标签上新增show-search、option-filter-prop="children"和filterOption,具体如下(按理来说和官网一样应该没问题,但也可能会有问题,比如我这里就出了问题):
// 标签上新增showSearch、option-filter-prop="children"和filterOption
<a-select placeholder="全部" v-model:value="formState.llcsSysType" :getPopupContainer="(triggerNode) => triggerNode.parentNode" show-search option-filter-prop="children" :filterOption="filterOption">
<a-select-option v-model:value="item.roleCode" v-for="(item, index) in roleArr" :key="index">
{{ item.roleName }}
</a-select-option>
</a-select>
// filterOption定义成一个方法单独拿出来方便复用
methods: {
filterOption(input, option) => {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
};
}
操作时发现始终提示Uncaught (in promise) TypeError: Cannot read property 'children' of undefine:

经过调试发现,我打印了下option发现它根本没有componentOptions属性并展开看了一下,这时我猜想可能是antd版本的问题,而我想要的数据竟然还在children数组的第一个元素的children属性中:

那么问题就清晰了,根据实际结构,我此处完整的修改如下:
// 标签上新增showSearch和filterOption
<a-select placeholder="全部" v-model:value="formState.llcsSysType" :getPopupContainer="(triggerNode) => triggerNode.parentNode" show-search option-filter-prop="children" :filterOption="filterOption">
<a-select-option v-model:value="item.roleCode" v-for="(item, index) in roleArr" :key="index">
{{ item.roleName }}
</a-select-option>
</a-select>
// filterOption定义成一个方法单独拿出来方便复用
methods: {
filterOption(input, option) => {
// 重点在这
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
};
}
到此,问题解决,能实现和官方案例一样的效果,但是这也暴露出来一个问题,就是我们项目中的filterOption中的参数option和官网案例中的option不是一个东西,从结构上看官网案例中的option应该是我们项目里的option.children[0],这也可能是我们项目引用的时候和官网的有所差异导致的,也有网上说是因为我们option中的内容前后带有空格导致其变成了数组,但潘老师也未能证实,不过好在最终还是解决了,完美!





