• 作者:老汪软件技巧
  • 发表时间:2024-08-25 21:13
  • 浏览量:

Ant Design 目前被广泛应用于企业级后台项目,甚至会被作为对外站点的 UI 库选择,构建 C 端业务。

其中,选择器组件 是平常后台页面开始中被频繁使用的组件,相较于 Input,交互更加繁多,功能更加丰富,本期就来介绍。

基本使用

与 HTML 原生 元素一样, 组件使用与之类似。

原生 元素:


渲染效果:

使用 Ant Design 组件:

使用

import { Select } from 'antd'
<Select style={{ width: 120 }}>
  <Select.Option value="">--Please choose an option--Select.Option>
  <Select.Option value="dog">DogSelect.Option>
  <Select.Option value="cat">CatSelect.Option>
Select>

渲染效果:

相较于原生 元素,Ant Design 提供的 组件是根据 placeholder 决定,决定选择组件的初始宽度,没有 placeholder 就没有初始长度,这是需要我们特别注意的。

为了让 组件渲染合适的宽度,需要我们手动指定。

- 

再次查看效果:

使用 options prop

使用 渲染选项的做法跟原生做法很像,不过代码写起来还是有些繁多。为此, 组件上提供了一个 ,直接以数组方式传入选项列表展示。

<Select
  style={{ width: 120 }}
  options={[
    { value: 'jack', label: 'Jack' },
    { value: 'lucy', label: 'Lucy' },
    { value: 'disabled', label: 'Disabled', disabled: true },
  ]}
/>

渲染效果:

值得注意的是,Options Prop 的需要是 { label, value }[]——label 表示展示的选项,value 则表示选项背后的 key 值,往往会传输给后端进行存储、标识。

当然,如果某些选项属于禁用状态,你还可以通过 disabled: true 方式禁用。

值得注意的是,在 5.11.0 版本后, 的使用方式已不再推荐,并计划在 6.0 后移除, 会成为唯一使用方式。

fieldNames prop

另外,如果你的 options 列表不是 { label, value } 结构也没有关系, 允许你通过 fieldNames prop 自定义。

我们稍微修改下上面的选项列表结构,并通过 fieldNames prop 自定义选项属性:

<Select
  style={{ width: 120 }}
  fieldNames={{
    label: 'name',
    value: 'key',
  }}
  options={[
    { key: 'jack', name: 'Jack' },
    { key: 'lucy', name: 'Lucy' },
    { key: 'disabled', name: 'Disabled', disabled: true },
  ]}
/>

以上,我们将列表项的展示属性设置成 name,列表项的标识属性设置成 key。

效果一样:

选项搜索showSearch prop

当然, 还内置了搜索能力,通过 showSearch prop 开启。

<Select
  showSearch
  placeholder="Select a person"
  options={[
    {
      value: 'jack',
      label: 'Jack',
    },
    {
      value: 'lucy',
      label: 'Lucy',
    }
  ]}
/>

渲染效果:

启用搜索能力后,就可以在输入框中输入搜索内容了:

optionFilterProp prop

默认使用的是 value 内容过滤的,通过 optionFilterProp prop 控制。

不过 optionFilterProp prop 默认 value 的设置跟我们直觉上的感受不太一致。因此,在实际使用中,我们通常会将 optionFilterProp prop 指定为 label。

<Select
  showSearch
  optionFilterProp="label"
  style={{ width: 200 }}
  placeholder="选择国家"
  options={[
    {
      value: 'china',
      label: 'China (中国)',
    },
    {
      value: 'usa',
      label: 'USA (美国)',
    },
    {
      value: 'japan',
      label: 'Japan (日本)'
    }
  ]}
/>

搜索时效果:

搜索中状态:

filterOption prop

不过,optionFilterProp prop 能力有限,有时候我们需要同时支持根据 value 或 label 字段进行过滤,那这个时候就可以使用 filterOption prop。

filterOption prop 可以指定一个函数,里面可以组织我们的自定义搜索逻辑。

<Select
    // ...
    filterOption={(inputValue, option) => {
    return (
      option.label.toLowerCase().indexOf(inputValue.toLowerCase()) >= 0 ||
      option.value.toLowerCase().indexOf(inputValue.toLowerCase()) >= 0
    )
  }}
/>

optionFilterProp prop 作为函数使用时,会接受两个参数:inputValue 和 option:inputValue 表示当前输入的搜索内容,option 表示当前的选择项。

函数返回 true 表示该选项是符合过滤条件的,应予以展示,反之则不然。

我们的筛选列表如下:

<Select
  // ...
  options={[
    {
      value: 'China',
      label: '中国',
    },
    {
      value: 'USA',
      label: '美国',
    },
    {
      value: 'Japan',
      label: '日本'
    }
  ]}
/>

下面,我们分别输入 value 及 label 的内容进行搜索,查看效果。

根据 label 搜索

根据 value 搜索

发现都是可以成功筛选的。

远程搜索

有时候我们的 options 选项数据不是写死在本地的,而是通过当前输入的搜索内容,动态从远程服务器上获取的。

针对这类场景,除了要给 启用 showSearch prop,还要额外附加几个 prop,能更好增加体验。

<Select
  // ...
  suffixIcon={null}
  filterOption={false}
  notFoundContent={null}
/>

观感上,变成一个搜索输入框了。

下面,我们在增加搜索逻辑:

<Select
  // ...
  onSearch={handleSearch}
  options={data}
/>

我们补充一下这 2 处的逻辑:

import jsonp from 'fetch-jsonp';
let timeout;
let currentValue;
const App = () => {
  const [data, setData] = useState([]);
  const fetch = (value, callback) => {
    clearTimeout(timeout)
    currentValue = value;
    const fake = () => {
      const searchParams = new URLSearchParams({
        code: 'utf-8',
        q: value,
      });
      jsonp(`https://suggest.taobao.com/sug?${searchParams}`)
        .then((response) => response.json())
        .then((d) => {
          if (currentValue === value) {
            const { result } = d;
            const data = result.map((item) => ({
              value: item[0],
              label: item[0],
            }));
            callback(data);
          }
        });
    };
    if (value) {
      timeout = setTimeout(fake, 300);
    } else {
      callback([]);
    }
  };
  const handleSearch = (newValue) => {
    fetch(newValue, setData);
  };
  
  // ...
}

查看效果:

当然,我们还可以将交互进一步细化,为数据加载中的增加一个后缀加载状态。

import { LoadingOutlined } from '@ant-design/icons'
import jsonp from 'fetch-jsonp';
const App = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);
  
  const fetch = (value, callback) => {
    const fake = () => {
      setLoading(true);
      // ...
      jsonp(`https://suggest.taobao.com/sug?${searchParams}`)
        .finally(() => {
          setLoading(false)
        })
      // ...
  }
  
  return (
   <Select
      showSearch
      placeholder="input search text"
      style={{ width: 200 }}
      filterOption={false}
      notFoundContent={null}
      onSearch={handleSearch}
      options={data}
      suffixIcon={loading ? <LoadingOutlined /> : null}
      loading={loading}
    />
  )
}

查看效果:

总结

本文我们介绍了 Ant Design 选择组件 的基本使用、选项搜索以及远程数据获取的编写方式,基本上能涵盖大多数的使用场景了。

更进一步的 的使用方式,我也许会在后面再开一篇文章介绍说明。

好了,本文内容就到此为止了。希望对你的工作能有所帮助,感谢你的阅读,再见。