一、自己写的组件
效果图
完整代码
App.js
import React, { Component } from "react";
import { Input, Checkbox } from 'antd';
import { CloseOutlined } from '@ant-design/icons';
import _ from "lodash";
import "antd/dist/antd.css";
import "./App.css"
const selectData = ["test1","test2","test3","test4"];
class App extends Component {constructor(props) {super(props);this.state = {selectValues: ["test1","test2","test3","test4"],inputValue: "",showCheckGroup: false,indeterminate: true,checkAll: true};this.deleteSelectSiteId = this.deleteSelectSiteId.bind(this);this.onSelectChange = this.onSelectChange.bind(this);}componentDidMount(){this.setState({indeterminate:selectData.length===this.state.selectValues.length?false:true,checkAll:!_.isEmpty(selectData)&!_.isEmpty(this.state.selectValues)&selectData.length===this.state.selectValues.length?true:false})}onSelectChange(value) {console.log("value===value.length",value,value.length);console.log("this.selectData",selectData)this.setState({selectValues: value,indeterminate: !!value.length && value.length < selectData.length,checkAll: value.length === selectData.length,});}handleInputChange(data) {console.log("data", data)this.setState({ inputValue: data })}deleteSelectSiteId(key) {const newSelectValues = this.state.selectValues;newSelectValues.splice(key, 1);this.setState({ selectValues: newSelectValues, inputValue: "" });}renderValueItem({ value, key }) {return (<divkey={key}className="selectBox"><span className="selectValue">{value}</span>{' '}<CloseOutlinedclassName="CloseOutlined"onClick={() => this.deleteSelectSiteId(key)}/></div>);}onCheckAllChange = e => {console.log("e.target.checked",e.target.checked)this.setState({inputValue: "",indeterminate: false,checkAll: e.target.checked,});if (e.target.checked) {this.setState({ selectValues: selectData });} else {this.setState({ selectValues: [""] });}};render() {return (<div className="selectContainer"onClick={() => { this.setState({ showCheckGroup: true }) }}><div className="selectValuesBox">{this.state.selectValues.length > 0 ?this.state.selectValues.map((value, key) => {return this.renderValueItem({ value, key });}): <div className="blanck_SelectBox"></div>}</div>{this.state.showCheckGroup &&<div className="CheckboxGroupBox" onMouseLeave={(e) => { this.setState({ showCheckGroup: false }) }}><Input className="selectInputSearch" placeholder="Type to Search" onChange={(e, data) => { this.handleInputChange(e.target.value) }} /><Checkboxindeterminate={this.state.indeterminate}onChange={this.onCheckAllChange}checked={this.state.checkAll}style={
{ marginLeft: 8 }}>All</Checkbox><br /><Checkbox.GroupclassName="CheckboxGroup"onChange={this.onSelectChange}value={this.state.selectValues}>{selectData.map((sel, i) => {return (<Checkbox className="Checkbox" value={sel} key={"select" + i} style={
{display: _.isEmpty(this.state.inputValue) ? "block": sel.indexOf(this.state.inputValue) === -1 ? "none": "block"}}>{sel}</Checkbox>);})}</Checkbox.Group></div>}</div>);}
}
export default App;
App.css
.selectContainer{position: relative;border: 1px solid #d9d9d9;border-radius: 4px;height: 32px;padding: 0 15px 0 10px;display: inline-block;}
.selectBox{ background-color: #fafafa;padding: 0 10px 0 10px;border: 1px solid #e8e8e8;border-radius: 2px;display: inline-block;margin-left: 5px}
.CloseOutlined{color: rgba(0, 0, 0, 0.45); font-weight: bold; font-size: 12px;}
.selectValue{font-size: 14px; color: rgba(0, 0, 0, 0.65);margin-right: 4px;height: auto;}
.selectValuesBox{margin-top: 3px;}
.Checkbox{margin-left: 8px;}
.CheckboxGroupBox{margin-top: 4px;margin-left: -12px;background-color: #fff;z-index: 999;position: absolute;border: 1px solid #d9d9d9;top: 100%;border-radius: 4px;width:240px;
}
.selectInputSearch{width: 214px;margin-top: 20px;margin-bottom: 10px;margin-left: 8px;border-radius: 4px;}
.blanck_SelectBox{display: inline-block;margin-left: 5px;padding: 0 10px 0 10px;}
二、网上找到了一个比较简洁好用的组件
App.js
import React, { Component } from "react";
import MultiSelect from "react-multi-select-component";
import "./App.css"
const options = [{ label: "Grapes ?", value: "grapes" },{ label: "Mango ?", value: "mango" },{ label: "Strawberry ?", value: "strawberry", disabled: true },{ label: "Watermelon ?", value: "watermelon" },{ label: "Pear ?", value: "pear" },{ label: "Apple ?", value: "apple" },{ label: "Tangerine ?", value: "tangerine" },{ label: "Pineapple ?", value: "pineapple" },{ label: "Peach ?", value: "peach" },
];
class App extends Component {constructor(props) {super(props);this.state = {selected: ""}this.setSelected = this.setSelected.bind(this);}setSelected(e) {this.setState({ selected: e })}render() {const CustomItemRenderer = ({ checked, option, onClick, disabled }) => {return (<div className={`item-renderer ${disabled && "disabled"}`}><label className="container"><inputtype="checkbox"onChange={onClick}checked={checked}tabIndex={-1}disabled={disabled}className="checkboxMulti"/><span className="checkmark_span" /></label><span className="optionLabel">{option.label}</span></div>);};return (<div><MultiSelectoptions={options}value={this.state.selected}onChange={this.setSelected}labelledBy={"Select"}ItemRenderer={CustomItemRenderer}selectAllLabel={"All Sites"}/><div className="testDiv"></div></div>)}
}
export default App;
App.css
.container {display: block;position: relative;padding-left: 35px;cursor: pointer;font-size: 14px;color: red;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;}/* Hide the browser's default checkbox */.container input {position: absolute;opacity: 0;cursor: pointer;height: 0;width: 0;}/* Create a custom checkbox */.checkmark_span {position: absolute;top: 4px !important;left: 0;height: 16px;width: 16px;background-color: #fff;border-radius: 3px;border: 1px solid #ddd;}/* On mouse-over, add a grey background color */.container:hover input ~ .checkmark_span {background-color: #fff;border: 1px solid #4b0f6d;}/* When the checkbox is checked, add a blue background */.container input:checked ~ .checkmark_span {background-color: #4b0f6d;}/* Create the checkmark/indicator (hidden when not checked) */.checkmark_span:after {content: "";position: relative;display: none;}/* Show the checkmark when checked */.container input:checked ~ .checkmark_span:after {display: block;}/* Style the checkmark/indicator */.container .checkmark_span:after {left: 4px;top: 1px;width: 3px;height: 7px;border: solid white;border-width: 0 3px 3px 0;-webkit-transform: rotate(45deg);-ms-transform: rotate(45deg);transform: rotate(45deg);}.item-renderer > span {margin-left: 2rem;}.multi-select {--rmsc-h: 32px!important;display: inline-block;}.dropdown-content {position: absolute;top: 100%;border-radius: 4px;width: 350px!important;}.optionLabel {font-size: 14px;}.select-panel > div {position: relative;width: 60%;top: 5px;left: 10px;border: none;height:32px;margin-bottom: 8px;}.select-panel input[type="search"] {padding-left: 0.5rem;border-radius: 5px;border: 1px solid #ddd;width: 214px;height:32px;}
项目中/node_modules/react-multi-select-component/src/select-panel/index.tsx文件可以查看这个组件的代码结构