该组件的功能有:
1.可设置搜索功能
2.可以每级可选,也可以选择只能最后一级里面的选项可选
3.当组件是只能最后一级里面的选项可选时, 点击文字展开下级选项
import React, { ReactNode, useEffect, useState } from 'react';import { Form, TreeSelect } from 'antd';import _, { get, isEmpty } from 'lodash';import styles from './SimpleTreeSelect.module.css';import { arrayLengthMoreThanZero } from 'utils/formatHelper';import './SimpleTreeSelect.css';interface ITreeSelectProps {label: string;name: any;required?: boolean;errorMessage?: string;placeHolder?: string;optionValue?: string;optionLabel?: string;value?: string;width?: string;addAll?: boolean;allOption?: object;labelStyle?: React.CSSProperties;containerStyle?: React.CSSProperties;disabled?: boolean;showSearch?: boolean;onChange?: (value: string, arg2?: ReactNode[], arg3?: any) => void;onFocus?: (arg: any) => void;allLabel?: string;allValue?: string;hideOptionValue?: string | string[];validator?: (arg1: any, arg2: any) => any;bottomContent?: string | JSX.Element;showArrowIcon?: boolean;option: ItreeNodeItem[];onLoadData?: (arg: any) => any;allCanSelect?: boolean;}interface ItreeNodeItem {id?: string;pId?: string;value?: string;title?: string;disabled?: boolean;isLeaf?: boolean;}export const SimpleTreeSelect = (props: ITreeSelectProps) => {const {label,name,required = false,errorMessage = '必选',// placeHolder = '请选择',value,option: initOption,width = 290,addAll = true,labelStyle,containerStyle,disabled = false,allOption,onChange,showSearch = true,allLabel = '全部',allValue = '',hideOptionValue,validator,bottomContent = '',showArrowIcon = true,onFocus,onLoadData,allCanSelect = false,} = props;const [option, setOption] = useState<any[]>(initOption);/*** option: select数据,为对象数组* 隐藏掉指定value的选项hideOptionValue* */useEffect(() => {if (allCanSelect) return;const option: any[] = initOption;for (let item of option) {const arr = (option || []).filter(its => get(its, ['pId']) === get(item, ['id'])) || [];item.disabled = arrayLengthMoreThanZero(arr);}if (addAll) {option.unshift({pId: allValue,value: allValue,title: allLabel,})}if (typeof hideOptionValue === 'string' && hideOptionValue) {const idx = _.findIndex(option, item => get(item, ['id']) === hideOptionValue);if (idx >= 0) option.splice(idx, 1);}if (arrayLengthMoreThanZero(hideOptionValue)) {const hideOption = hideOptionValue || []const arr: any[] = _.filter(option, item => {for (let its of hideOption) {if (get(item, ['id']) !== its) return item;}}) || [];setOption(arr);}else {setOption(option);}}, [initOption, hideOptionValue, allCanSelect]);const placeHolder = props.placeHolder || (disabled ? '' : '请选择');const renderLabel = () => {return (<span className={styles.label} style={labelStyle}>{required && <span className={styles.star}>*</span>}{label}</span>);};const renderArrowIcon = () => showArrowIcon ? <span className={styles.arrowIcon} /> : <></>;return (<div style={containerStyle} className={styles.selectContainer}><Form.Item colon={false} label={renderLabel()}><Form.Itemname={name}colon={false}noStylevalidateFirstinitialValue={value}rules={validator? [{ required: required, message: errorMessage }, { validator }]: [{ required: required, message: errorMessage }]}><TreeSelecttreeDataSimpleModeshowSearch={showSearch}treeNodeFilterProp={'title'}//输入项过滤对应的 treeNode 属性, value或者titlestyle={{ width: width && /^\d+$/.test(width.toString()) ? `${width}px` : width }}dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}allowCleartreeDefaultExpandAll={false}onChange={(value, label, extra) => {onChange && onChange(value, label, extra)}}onClick={e=> {const vvv:any = e.target||{};const el:any = get(vvv.parentNode.children, [1]) || get(vvv.parentNode.parentNode.children, [1]);try {if('click' in el) {el.click();}else {const evt:any = document.createEvent('Event');evt.initEvent('click', true, true);el.dispatchEvent(evt);}}catch(err) {console.log(err)}}}onFocus={onFocus}loadData={onLoadData}value={value}placeholder={placeHolder}treeData={option}disabled={disabled}suffixIcon={renderArrowIcon()}></TreeSelect></Form.Item>{!isEmpty(bottomContent) && <div style={{ margin: 0 }}><div style={{ marginBottom: '-5px' }}>{bottomContent}</div></div>}</Form.Item></div>);};
treeData数据示例:
const arr0 = [
{
id: 1,
pId: 0,
value: 'leaf-1',
title: '属性图1'
},
{
id: 2,
pId: 1,
value: 'leaf-2',
title: '属性图2'
},
{
id: 3,
pId: 0,
value: 'leaf-3',
title: '属性图3'
}
];
let [treeData, setTreeData] = useState<any[]>(arr0);
CustomSimpleTreeSelect的简单使用:
<CustomSimpleTreeSelect
option={treeData}
labelStyle={labelStyle}
containerStyle={containerStyle}
addAll={false}
name="xxx"
label="xxx"
required
/>