深入了解antd select 组件过滤功能

1,101 阅读3分钟

需求背景

最近接到一个需求, 需求内容是将国家数据分组展示并且支持多选, 于是我就想到用Select.OptGroup来实现; OptGroup实现数据分组后, 无法根据国家名称第一时间过滤出数据,只能根据组名进行过滤带出该组下所有的数据, 但问题是我并不了解都有哪些组别且也不了解查询的数据属于哪个组别下.

问题

select分组后如何支持数据过滤(跟未分组一样的效果)

解决方案

确定antd版本

为了更好的定位问题我查看了项目中使用的antd版本,确定好大版本后,到github找到对应的下载源码.
当然你也可以通过打开codespaces的方式在将github上的代码在本地vscode上打开.或者也可以在github上打开打开网页版的vscode

查看antd select源码

  • 直接查看select源码
    在查看select源码前,我猜想select过滤功能的实现方案: 获取input输入数据,对options中数据的label进行filter过滤,找到并返回满足条件的数据.按照这个思路去查看select源码,发现很多代码看的头疼,而且也不知道在做什么,而我的目的也只是快速定位到我需要的代码

  • 查找input change方法
    根据select实现的猜想, 我只要找到select组件中input输入框子元素的onchange方法,由这个方法去反推向上查找select的是实现...这个方式也不行...因为antd里面不是使用这种方案实现

  • 查找displayOptions来源
    select过滤后数据的变化在列表体现, 所以我选择通过下拉列表中的数据的来源去向上查找, 最终找到了hooks/useOptions文件, 这个hook对options和children的数据进行规范化处理, Select.Option组件在这里被转换为options的格式,在这过程中涉及到options与Select.Option同时使用的优先级问题

  • options与Select.Option优先级
    options和Select.Option标签一起使用时,options的优先级高于Select.Option.下面代码表示当options不存在时,取children数据作为options选项.

image.png

  • Select.Option + Select.OptGroup转换为options数组的数据格式
    convertChildrenToData(children)方法将Select.Option + Select.OptGroup转换为options数组的数据格式,如下所示
{
    label,
    key,
    options: [
        {
            children,
            value,
            key
        }
    ]
}

image.png

确定实现

  • useFilterOptions监听输入内容变化过滤Options useFilterOptions中对数据的筛选做了几个兼容方案: optionFilterProp > fieldNames.label > fieldNames.value

image.png

解决问题

根据useFilterOptions的实现, 在select组件中传入optionFilterProp="children"的属性即可.

例子

本篇文章的代码在codesandbox

延伸

compositionStart与compositionEnd

  • compositionstart: 文本段落的开始输入时触发
  • compositionEnd: 文本段落的组成完成或取消时触发
    在搜索框的功能中经常出现的需求是: 远程搜索与模糊搜索.往往我们输入拼音时,就带出一连串的接口请求,为了避免这些问题我们想在拼音输入法输入完成后才触发接口请求或者是数据模糊搜索. 目前这两个api是解决这个问题的最佳方式