antd实现select下拉框带有搜索筛选功能报错option.children.toLowerCase is not a function

Web前端 潘老师 3年前 (2021-08-04) 5781 ℃ (0) 扫码查看

最近在被安排去做前端开发,由于下拉框中的数据可能太多,滚动一个个翻着来查找影响效率,因此需要实现下拉框带有根据输入进行筛选的功能,由于本项目是用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-searchoption-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
antd实现select下拉框带有搜索筛选功能报错option.children.toLowerCase is not a function
经过调试发现,我打印了下option发现它根本没有componentOptions属性并展开看了一下,这时我猜想可能是antd版本的问题,而我想要的数据竟然还在children数组的第一个元素的children属性中:
antd实现select下拉框带有搜索筛选功能报错option.children.toLowerCase is not a function
那么问题就清晰了,根据实际结构,我此处完整的修改如下:

// 标签上新增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
    };
}
提示:option-filter-prop=”children”也可以去掉,不影响搜索

到此,问题解决,能实现和官方案例一样的效果,但是这也暴露出来一个问题,就是我们项目中的filterOption中的参数option和官网案例中的option不是一个东西,从结构上看官网案例中的option应该是我们项目里的option.children[0],这也可能是我们项目引用的时候和官网的有所差异导致的,也有网上说是因为我们option中的内容前后带有空格导致其变成了数组,但潘老师也未能证实,不过好在最终还是解决了,完美!


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/java/web/3417.html
喜欢 (2)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】