Ant Design Select 分页下拉允许搜索

馋奶兔 提交于 2020-08-19 19:02:34

基于Ant Design Select组件

📙 项目地址 :

     👉 GitHub地址: https://github.com/zlinggnilz/work-demo/blob/master/src/components/CustomSelect/index.js

     👉 查看在线示例:https://codesandbox.io/s/funny-worker-lrhvt

 

📘 定制化组件 CustomSelect :

不传入children,通过dataSource传入数组遍历出option,数组元素包含key 和 label

组件 CustomSelect 代码:

import React from "react";
import { Select } from "antd";
import PropTypes from "prop-types";

const { Option } = Select;

export default class CustomSelect extends React.Component {
  static propTypes = {
    dataSource: PropTypes.arrayOf(
      PropTypes.shape({
        key: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
          .isRequired,
        label: PropTypes.string
      })
    ),
    onChange: PropTypes.func
  };

  static defaultProps = {
    dataSource: []
  };

  constructor(props) {
    super(props);
    this.state = {
      page: 1,
      showArr: props.dataSource
    };
    this.pageSize = 20;
    this.list = [];
  }

  pageSt = 0;

  handleChange = v => {
    const { onChange, dataSource } = this.props;
    onChange && onChange(v);
    this.setState({ page: 1, showArr: dataSource });
  };

  handlePopupScroll = e => {
    const { page, showArr } = this.state;
    e.persist();
    const { target } = e;
    const st = target.scrollTop;
    if (st === 0 && this.pageSt) {
      target.scrollTop = this.pageSt;
    }
    if (
      st + target.offsetHeight + 2 >= target.scrollHeight &&
      this.list.length < showArr.length
    ) {
      this.setState({ page: page + 1 });
      this.pageSt = st;
    } else {
      this.pageSt = 0;
    }
  };

  handleFocus = () => {
    this.prevScroll = 0;
    const { dataSource } = this.props;
    this.setState({ page: 1, showArr: dataSource });
  };

  handleSearch = v => {
    const { dataSource } = this.props;
    v = v || "";
    const filterWord = v.trim().toLowerCase();
    const showArr = dataSource.filter(item =>
      item.label.toLowerCase().includes(filterWord)
    );
    this.setState({ page: 1, showArr });
  };

  render() {
    const { dataSource, ...rest } = this.props;
    const { showArr, page } = this.state;
    if (showArr.length > this.pageSize) {
      this.list = showArr.slice(0, this.pageSize * page);
      // 当value是外部赋值的时候,判断value是否在当前的list中,如果不在,单独加进来
      if (this.props.value != null) {
        let valueObj = this.list.find(item => item.key === this.props.value);
        if (!valueObj) {
          valueObj = dataSource.find(item => item.key === this.props.value);
          valueObj && this.list.unshift(valueObj);
        }
      }
    } else {
      this.list = showArr;
    }
    return (
      <Select
        {...rest}
        onChange={this.handleChange}
        filterOption={false}
        onPopupScroll={this.handlePopupScroll}
        onFocus={this.handleFocus}
        onSearch={this.handleSearch}
      >
        {this.list.map(opt => (
          <Option key={opt.key} value={opt.key}>
            {opt.label || opt.key}
          </Option>
        ))}
      </Select>
    );
  }
}

 

 

使用示例:

const SearchInput = () => {
  const arr = [{ label: "test text", key: "test" }];
  for (let i = 0; i < 500; i++) {
    arr.push({
      label: `label-${i}`,
      key: i,
    });
  }
  return <CustomSelect showSearch dataSource={arr} placeholder="Custom select" style={{ width: 180 }} />;
};

 

📚参考:

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!