欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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)文章

  • Shopee在React?Native?架構(gòu)方面的探索及發(fā)展歷程

    Shopee在React?Native?架構(gòu)方面的探索及發(fā)展歷程

    這篇文章主要介紹了Shopee在React?Native?架構(gòu)方面的探索,本文會(huì)從發(fā)展歷史、架構(gòu)模型、系統(tǒng)設(shè)計(jì)、遷移方案四個(gè)方向逐一介紹我們?nèi)绾我徊讲降貪M足多團(tuán)隊(duì)在復(fù)雜業(yè)務(wù)中的開(kāi)發(fā)需求,需要的朋友可以參考下
    2022-07-07
  • ForwardRef?useImperativeHandle方法demo

    ForwardRef?useImperativeHandle方法demo

    這篇文章主要為大家介紹了ForwardRef?useImperativeHandle方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 詳解React中的setState執(zhí)行機(jī)制

    詳解React中的setState執(zhí)行機(jī)制

    setState是React組件中用于更新?tīng)顟B(tài)的方法,是類組件中的方法,用于更新組件的狀態(tài)并重新渲染組件,本文給大家詳細(xì)介紹了React中的setState執(zhí)行機(jī)制,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • react學(xué)習(xí)每天一個(gè)hooks?useWhyDidYouUpdate

    react學(xué)習(xí)每天一個(gè)hooks?useWhyDidYouUpdate

    這篇文章主要為大家介紹了react學(xué)習(xí)每天一個(gè)hooks?useWhyDidYouUpdate使用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • react項(xiàng)目打包后點(diǎn)擊index.html頁(yè)面出現(xiàn)空白的問(wèn)題

    react項(xiàng)目打包后點(diǎn)擊index.html頁(yè)面出現(xiàn)空白的問(wèn)題

    這篇文章主要介紹了react項(xiàng)目打包后點(diǎn)擊index.html頁(yè)面出現(xiàn)空白的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Remix后臺(tái)開(kāi)發(fā)之remix-antd-admin配置過(guò)程

    Remix后臺(tái)開(kāi)發(fā)之remix-antd-admin配置過(guò)程

    這篇文章主要為大家介紹了Remix后臺(tái)開(kāi)發(fā)之remix-antd-admin配置過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • React路由規(guī)則定義與聲明式導(dǎo)航及編程式導(dǎo)航分別介紹

    React路由規(guī)則定義與聲明式導(dǎo)航及編程式導(dǎo)航分別介紹

    這篇文章主要介紹了React路由規(guī)則的定義、聲明式導(dǎo)航、編程式導(dǎo)航,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-09-09
  • 路由react-router-dom的基本使用教程

    路由react-router-dom的基本使用教程

    在React中,路由是一套映射規(guī)則,是URL路徑與組件的對(duì)應(yīng)關(guān)系。使用React路由,就是配置路徑和組件的對(duì)應(yīng)關(guān)系,這篇文章主要介紹了路由react-router-dom的使用,需要的朋友可以參考下
    2023-02-02
  • JavaScript React如何修改默認(rèn)端口號(hào)方法詳解

    JavaScript React如何修改默認(rèn)端口號(hào)方法詳解

    這篇文章主要介紹了JavaScript React如何修改默認(rèn)端口號(hào)方法詳解,文中通過(guò)步驟圖片解析介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能

    使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能

    這篇文章主要介紹了使用React Native創(chuàng)建以太坊錢包,實(shí)現(xiàn)轉(zhuǎn)賬等功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07

最新評(píng)論