基于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 }} />;
};
📚参考:
来源:oschina
链接:https://my.oschina.net/u/4295934/blog/4411908