该组件的功能有:
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(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 (
{required && *}
{label}
);
};
const renderArrowIcon = () => showArrowIcon ? : <>>;
return (
{
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()}
>
{!isEmpty(bottomContent) &&
{bottomContent}
}
);
};
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
CustomSimpleTreeSelect的简单使用:
labelStyle={labelStyle}
containerStyle={containerStyle}
addAll={false}
name="xxx"
label="xxx"
required
/>