react简单封装antd的树形下拉框

该组件的功能有:

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(arr0);

CustomSimpleTreeSelect的简单使用:
            option={treeData}
          labelStyle={labelStyle}
          containerStyle={containerStyle}
          addAll={false}
          name="xxx"
          label="xxx"
          required
        />

你可能感兴趣的:(react,react.js,javascript,前端)