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


    该组件的功能有:

    1.可设置搜索功能

    2.可以每级可选,也可以选择只能最后一级里面的选项可选

    3.当组件是只能最后一级里面的选项可选时, 点击文字展开下级选项

    1. import React, { ReactNode, useEffect, useState } from 'react';
    2. import { Form, TreeSelect } from 'antd';
    3. import _, { get, isEmpty } from 'lodash';
    4. import styles from './SimpleTreeSelect.module.css';
    5. import { arrayLengthMoreThanZero } from 'utils/formatHelper';
    6. import './SimpleTreeSelect.css';
    7. interface ITreeSelectProps {
    8. label: string;
    9. name: any;
    10. required?: boolean;
    11. errorMessage?: string;
    12. placeHolder?: string;
    13. optionValue?: string;
    14. optionLabel?: string;
    15. value?: string;
    16. width?: string;
    17. addAll?: boolean;
    18. allOption?: object;
    19. labelStyle?: React.CSSProperties;
    20. containerStyle?: React.CSSProperties;
    21. disabled?: boolean;
    22. showSearch?: boolean;
    23. onChange?: (value: string, arg2?: ReactNode[], arg3?: any) => void;
    24. onFocus?: (arg: any) => void;
    25. allLabel?: string;
    26. allValue?: string;
    27. hideOptionValue?: string | string[];
    28. validator?: (arg1: any, arg2: any) => any;
    29. bottomContent?: string | JSX.Element;
    30. showArrowIcon?: boolean;
    31. option: ItreeNodeItem[];
    32. onLoadData?: (arg: any) => any;
    33. allCanSelect?: boolean;
    34. }
    35. interface ItreeNodeItem {
    36. id?: string;
    37. pId?: string;
    38. value?: string;
    39. title?: string;
    40. disabled?: boolean;
    41. isLeaf?: boolean;
    42. }
    43. export const SimpleTreeSelect = (props: ITreeSelectProps) => {
    44. const {
    45. label,
    46. name,
    47. required = false,
    48. errorMessage = '必选',
    49. // placeHolder = '请选择',
    50. value,
    51. option: initOption,
    52. width = 290,
    53. addAll = true,
    54. labelStyle,
    55. containerStyle,
    56. disabled = false,
    57. allOption,
    58. onChange,
    59. showSearch = true,
    60. allLabel = '全部',
    61. allValue = '',
    62. hideOptionValue,
    63. validator,
    64. bottomContent = '',
    65. showArrowIcon = true,
    66. onFocus,
    67. onLoadData,
    68. allCanSelect = false,
    69. } = props;
    70. const [option, setOption] = useState<any[]>(initOption);
    71. /**
    72. * option: select数据,为对象数组
    73. * 隐藏掉指定value的选项hideOptionValue
    74. *
    75. */
    76. useEffect(() => {
    77. if (allCanSelect) return;
    78. const option: any[] = initOption;
    79. for (let item of option) {
    80. const arr = (option || []).filter(its => get(its, ['pId']) === get(item, ['id'])) || [];
    81. item.disabled = arrayLengthMoreThanZero(arr);
    82. }
    83. if (addAll) {
    84. option.unshift({
    85. pId: allValue,
    86. value: allValue,
    87. title: allLabel,
    88. })
    89. }
    90. if (typeof hideOptionValue === 'string' && hideOptionValue) {
    91. const idx = _.findIndex(option, item => get(item, ['id']) === hideOptionValue);
    92. if (idx >= 0) option.splice(idx, 1);
    93. }
    94. if (arrayLengthMoreThanZero(hideOptionValue)) {
    95. const hideOption = hideOptionValue || []
    96. const arr: any[] = _.filter(option, item => {
    97. for (let its of hideOption) {
    98. if (get(item, ['id']) !== its) return item;
    99. }
    100. }) || [];
    101. setOption(arr);
    102. }
    103. else {
    104. setOption(option);
    105. }
    106. }, [initOption, hideOptionValue, allCanSelect]);
    107. const placeHolder = props.placeHolder || (disabled ? '' : '请选择');
    108. const renderLabel = () => {
    109. return (
    110. <span className={styles.label} style={labelStyle}>
    111. {required && <span className={styles.star}>*</span>}
    112. {label}
    113. </span>
    114. );
    115. };
    116. const renderArrowIcon = () => showArrowIcon ? <span className={styles.arrowIcon} /> : <></>;
    117. return (
    118. <div style={containerStyle} className={styles.selectContainer}>
    119. <Form.Item colon={false} label={renderLabel()}>
    120. <Form.Item
    121. name={name}
    122. colon={false}
    123. noStyle
    124. validateFirst
    125. initialValue={value}
    126. rules={
    127. validator
    128. ? [{ required: required, message: errorMessage }, { validator }]
    129. : [{ required: required, message: errorMessage }]
    130. }
    131. >
    132. <TreeSelect
    133. treeDataSimpleMode
    134. showSearch={showSearch}
    135. treeNodeFilterProp={'title'}//输入项过滤对应的 treeNode 属性, value或者title
    136. style={{ width: width && /^\d+$/.test(width.toString()) ? `${width}px` : width }}
    137. dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
    138. allowClear
    139. treeDefaultExpandAll={false}
    140. onChange={(value, label, extra) => {
    141. onChange && onChange(value, label, extra)
    142. }}
    143. onClick={e=> {
    144. const vvv:any = e.target||{};
    145. const el:any = get(vvv.parentNode.children, [1]) || get(vvv.parentNode.parentNode.children, [1]);
    146. try {
    147. if('click' in el) {
    148. el.click();
    149. }
    150. else {
    151. const evt:any = document.createEvent('Event');
    152. evt.initEvent('click', true, true);
    153. el.dispatchEvent(evt);
    154. }
    155. }
    156. catch(err) {
    157. console.log(err)
    158. }
    159. }}
    160. onFocus={onFocus}
    161. loadData={onLoadData}
    162. value={value}
    163. placeholder={placeHolder}
    164. treeData={option}
    165. disabled={disabled}
    166. suffixIcon={renderArrowIcon()}
    167. >
    168. </TreeSelect>
    169. </Form.Item>
    170. {!isEmpty(bottomContent) && <div style={{ margin: 0 }}>
    171. <div style={{ marginBottom: '-5px' }}>
    172. {bottomContent}
    173. </div>
    174. </div>}
    175. </Form.Item>
    176. </div>
    177. );
    178. };

    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
            />

  • 相关阅读:
    Linux由hello.c生成a.out整个过程
    Python武器库开发-面向对象篇(五)
    腾讯即将开源微信、QQ都在用的动画神器;Linux Mint与Mozilla达成合作;Apache Flink ML 2.0.0发布 | 开源日报
    ElasticSearch7.3学习(二十七)----聚合概念(bucket和metric)及其示例
    正则表达式符号
    IOS Swift 从入门到精通: 可选项、展开和类型转换
    如何实现毫米波波束成形和大规模MiMo?
    WSL2的安装与配置(创建Anaconda虚拟环境、更新软件包、安装PyTorch、VSCode)
    关于ETL的两种架构(ETL架构和ELT架构)
    这些论文的作者居然是猫、狗、仓鼠……
  • 原文地址:https://blog.csdn.net/qq_42750608/article/details/127117807