Ant Design Select 分页下拉允许搜索
基于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 }} />; };
📚参考: