最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

react+antd樹(shù)選擇下拉框中增加搜索框

 更新時(shí)間:2023年06月07日 15:34:17   作者:司寧  
這篇文章主要介紹了react+antd樹(shù)選擇下拉框中增加搜索框方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

react antd樹(shù)選擇下拉框中增加搜索框

ant Design提供的樹(shù)選擇提供了搜索功能,但是這個(gè)搜索功能是在樹(shù)選擇的選擇框內(nèi),現(xiàn)在的需求是要把搜索功能抽離到下拉框中。(官方提供的方法是只要加上showSearch就可以實(shí)現(xiàn)搜索功能)。

function AdvancedSelect(props) {
? const [treeData] = props; // 下拉框數(shù)據(jù)
? const [searchValue, setSearchValue] = useState(''); // 搜索框值
? const [val, setVal] = useState([]); // 樹(shù)選擇框的值
? // 搜索框的值發(fā)生改變searchValue值也跟著改變
? const handleChangeSearch = (e) => {
? ? setSearchValue(e.target.value || '');
? };
? // 下拉數(shù)據(jù)二級(jí)處理
? const formatChildTreeData = (data, result) => {
? ? data.forEach((cur) => {
? ? ? if (cur.title.includes(searchValue)) {
? ? ? ? result.push(cur);
? ? ? } else if (cur.children && cur.children.length) {
? ? ? ? const childResult = formatChildTreeData(cur.children, result);
? ? ? ? if (childResult.length) {
? ? ? ? ? result.push({
? ? ? ? ? ? ...cur,
? ? ? ? ? ? children: childResult,
? ? ? ? ? });
? ? ? ? }
? ? ? }
? ? });
? ? return result;
? };
? // 處理下拉框數(shù)據(jù)
? const formatTreeData = () => {
? ? // 當(dāng)搜索框沒(méi)有值的時(shí)候不做處理
? ? if (!searchValue) return treeData;
? ? const result = [];
? ? treeData.forEach((item) => {
? ? ? if (item.title.includes(searchValue)) {
? ? ? ? result.push(item);
? ? ? } else if (item.children && item.children.length) {
? ? ? ? const childResult: ITreeDataItem[] = formatChildTreeData(
? ? ? ? ? item.children,
? ? ? ? ? [],
? ? ? ? );
? ? ? ? if (childResult.length) {
? ? ? ? ? result.push({
? ? ? ? ? ? ...item,
? ? ? ? ? ? children: childResult,
? ? ? ? ? });
? ? ? ? }
? ? ? }
? ? });
? ? return result;
? };
? const handleChange = (changedValue) => {
? ? const _val = changedValue.map((item) => item.value);
? ? setVal(_val);
? };
? return (
? ? <div>
? ? ? <TreeSelect
? ? ? ? style={{
? ? ? ? ? width: '100%',
? ? ? ? }}
? ? ? ? value={val}
? ? ? ? treeData={formatTreeData()}
? ? ? ? treeCheckable //顯示 Checkbox
? ? ? ? onDropdownVisibleChange={() => setSearchValue('')} // 展開(kāi)下拉菜單的回調(diào)
? ? ? ? dropdownRender={(menu) => (
? ? ? ? ? <>
? ? ? ? ? ? <Input
? ? ? ? ? ? ? onChange={handleChangeSearch}
? ? ? ? ? ? ? value={searchValue}
? ? ? ? ? ? ? placeholder="請(qǐng)搜索"
? ? ? ? ? ? />
? ? ? ? ? ? {menu}
? ? ? ? ? </>
? ? ? ? )} // 自定義下拉框內(nèi)容
? ? ? ? onChange={handleChange}
? ? ? ? treeNodeFilterProp: 'title' // 輸入項(xiàng)過(guò)濾對(duì)應(yīng)的 treeNode 屬性
? ? ? ? placeholder: '請(qǐng)選擇'
? ? ? />
? ? </div>
? );
}

這里的樹(shù)選擇下拉框的數(shù)據(jù)是從其他組件傳遞過(guò)來(lái)的,格式為:

const treeData = [
? {
? ? title: 'Node1',
? ? value: '0-0',
? ? key: '0-0',
? ? children: [
? ? ? {
? ? ? ? title: 'Child Node1',
? ? ? ? value: '0-0-0',
? ? ? ? key: '0-0-0',
? ? ? },
? ? ],
? },
? {
? ? title: 'Node2',
? ? value: '0-1',
? ? key: '0-1',
? ? children: [
? ? ? {
? ? ? ? title: 'Child Node3',
? ? ? ? value: '0-1-0',
? ? ? ? key: '0-1-0',
? ? ? },
? ? ? {
? ? ? ? title: 'Child Node4',
? ? ? ? value: '0-1-1',
? ? ? ? key: '0-1-1',
? ? ? },
? ? ? {
? ? ? ? title: 'Child Node5',
? ? ? ? value: '0-1-2',
? ? ? ? key: '0-1-2',
? ? ? },
? ? ],
? },
];

react簡(jiǎn)單封裝antd的樹(shù)形下拉框

該組件的功能有

1.可設(shè)置搜索功能

2.可以每級(jí)可選,也可以選擇只能最后一級(jí)里面的選項(xiàng)可選

3.當(dāng)組件是只能最后一級(jí)里面的選項(xiàng)可選時(shí), 點(diǎn)擊文字展開(kāi)下級(jí)選項(xiàng)

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 = '請(qǐng)選擇',
    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數(shù)據(jù),為對(duì)象數(shù)組
   * 隱藏掉指定value的選項(xiàng)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 ? '' : '請(qǐng)選擇');
  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.Item
          name={name}
          colon={false}
          noStyle
          validateFirst
          initialValue={value}
          rules={
            validator
              ? [{ required: required, message: errorMessage }, { validator }]
              : [{ required: required, message: errorMessage }]
          }
        >
          <TreeSelect
            treeDataSimpleMode
            showSearch={showSearch}
            treeNodeFilterProp={'title'}//輸入項(xiàng)過(guò)濾對(duì)應(yīng)的 treeNode 屬性, value或者title
            style={{ width: width && /^\d+$/.test(width.toString()) ? `${width}px` : width }}
            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
            allowClear
            treeDefaultExpandAll={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數(shù)據(jù)示例

? 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的簡(jiǎn)單使用

?<CustomSimpleTreeSelect
? ? ? ? ? option={treeData}
? ? ? ? ? labelStyle={labelStyle}
? ? ? ? ? containerStyle={containerStyle}
? ? ? ? ? addAll={false}
? ? ? ? ? name="xxx"
? ? ? ? ? label="xxx"
? ? ? ? ? required
? ? ? ? />

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • react實(shí)現(xiàn)消息顯示器

    react實(shí)現(xiàn)消息顯示器

    這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)消息顯示器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • React項(xiàng)目中axios的封裝與API接口的管理詳解

    React項(xiàng)目中axios的封裝與API接口的管理詳解

    Axios是一個(gè)npm軟件包,允許應(yīng)用程序?qū)TTP請(qǐng)求發(fā)送到Web API,下面這篇文章主要給大家介紹了關(guān)于React項(xiàng)目中axios的封裝與API接口的管理的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • JavaScript中React 面向組件編程(下)

    JavaScript中React 面向組件編程(下)

    在React面向組件編程中,除了上一章節(jié)的組件實(shí)例的三大核心屬性以外,還有很多重要的內(nèi)容比如:React 的生命周期,受控組件與非受控組件,高階函數(shù)和函數(shù)柯里化的理解等,在本文中會(huì)給大家繼續(xù)講解React 面向組件編程中剩余的內(nèi)容
    2023-03-03
  • React項(xiàng)目使用ES6解決方案及JSX使用示例詳解

    React項(xiàng)目使用ES6解決方案及JSX使用示例詳解

    這篇文章主要為大家介紹了React項(xiàng)目使用ES6解決方案及JSX使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React組件通信的實(shí)現(xiàn)示例

    React組件通信的實(shí)現(xiàn)示例

    在React中,組件通信是一個(gè)重要的概念,它允許不同組件之間進(jìn)行數(shù)據(jù)傳遞和交互,本文主要介紹了React組件通信的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2023-11-11
  • React useEffect、useLayoutEffect底層機(jī)制及區(qū)別介紹

    React useEffect、useLayoutEffect底層機(jī)制及區(qū)別介紹

    useEffect 是 React 中的一個(gè) Hook,允許你在函數(shù)組件中執(zhí)行副作用操作,本文給大家介紹React useEffect、useLayoutEffect底層機(jī)制及區(qū)別介紹,感興趣的朋友一起看看吧
    2025-04-04
  • React路由中的redux和redux知識(shí)點(diǎn)拓展

    React路由中的redux和redux知識(shí)點(diǎn)拓展

    這篇文章主要介紹了React路由中的redux和redux知識(shí)點(diǎn)拓展,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的朋友可以參考學(xué)習(xí)一下
    2022-08-08
  • React實(shí)現(xiàn)自動(dòng)滾動(dòng)表格的方法實(shí)例

    React實(shí)現(xiàn)自動(dòng)滾動(dòng)表格的方法實(shí)例

    React中實(shí)現(xiàn)一個(gè)自動(dòng)滾動(dòng)的表格,結(jié)合CSS動(dòng)畫(huà)與JavaScript定時(shí)器,支持手動(dòng)暫停、恢復(fù)及懸??刂?具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-09-09
  • react實(shí)現(xiàn)一個(gè)優(yōu)雅的圖片占位模塊組件詳解

    react實(shí)現(xiàn)一個(gè)優(yōu)雅的圖片占位模塊組件詳解

    這篇文章主要給大家介紹了關(guān)于react如何實(shí)現(xiàn)一個(gè)還算優(yōu)雅的占位模塊圖片組件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • React中的useEffect(副作用)介紹

    React中的useEffect(副作用)介紹

    這篇文章主要介紹了React中的useEffect(副作用),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論

大荔县| 锡林浩特市| 樟树市| 永和县| 古田县| 通城县| 秭归县| 南京市| 屏边| 阿瓦提县| 浪卡子县| 金堂县| 辰溪县| 永城市| 普兰店市| 乌兰县| 阿瓦提县| 英山县| 和顺县| 拉孜县| 大安市| 林周县| 抚顺市| 大邑县| 沙田区| 静海县| 诸城市| 澄江县| 法库县| 栖霞市| 开阳县| 石柱| 天柱县| 芮城县| 东平县| 江油市| 木里| 嘉善县| 凭祥市| 民丰县| 宝丰县|