1.3.3 • Published 3 days ago

react-cascader-popover v1.3.3

Weekly downloads
-
License
-
Repository
github
Last release
3 days ago

react-cascader-popover

react 级联选择器/支持多选/单选

src/Type 有完整演示

Install

 npm   i react-cascader-popover
或者
 yarn add react-cascader-popover

demo

https://react-cascader-popover-eyrp.vercel.app/

单选

npm.io

import { useRef, useState } from "react";
import { province } from "../data";
import {
  Cascader,
  CascaderOption,
  CascaderRefProps,
} from "react-cascader-popover";

function Default() {
  const [anchorEl, setAnchorEl] = useState<HTMLDivElement | null>(null);

  const [valueAllPath, setValueAllPath] = useState<CascaderOption[]>([]);

  const [value, setValue] = useState("120103");

  const cascaderRef = useRef<CascaderRefProps>(null);

  // 点击展开
  const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
    setAnchorEl(event.currentTarget);
  };
  // change 事件
  const handleChange = (
    value: CascaderOption | null,
    valueAll: CascaderOption[]
  ) => {
    setValue(value ? value.value : "");
    setValueAllPath(valueAll);
  };
  // 清空选中
  const handleClear = () => {
    setValueAllPath([]);
    // 两种都可以清空
    // setValue("");
    cascaderRef.current?.clearValue();
  };

  // 设置选中
  const handleSet = () => {
    setValue("11010333555");
  };

  const open = Boolean(anchorEl);
  return (
    <>
      <div style={{ width: "500px" }}>
        <div className="cascader">
          <div className="cascader_input_box" onClick={handleClick}>
            {valueAllPath.length ? (
              <div className="cascader_input">
                {valueAllPath.map((e) => e.label).join(" - ")}
              </div>
            ) : (
              <div className="placeholder">请选择</div>
            )}
          </div>
        </div>
      </div>

      <Cascader
        ref={cascaderRef}
        value={value}
        open={open}
        anchorEl={anchorEl}
        options={province}
        onClose={() => setAnchorEl(null)}
        onChange={handleChange}
      />
    </>
  );
}

export default Default;

多选

npm.io

  import { useRef, useState } from "react";
import {
  Cascader,
  CascaderOption,
  CascaderRefProps,
} from "react-cascader-popover";
import { province } from "../data";

function Multiple() {
  const value = "130102";
  const [anchorEl, setAnchorEl] = useState<HTMLDivElement | null>(null);
  const [valueAll, setValueAll] = useState<CascaderOption[]>([]);
  const cascaderRef = useRef<CascaderRefProps>(null);

  const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
    setAnchorEl(event.currentTarget);
  };
  const handleChange = (
    _: CascaderOption | null,
    valueAll: CascaderOption[]
  ) => {
    console.log(valueAll);

    setValueAll(valueAll);
  };
  const handleClear = () => {
    // cascaderRef.current?.setValue([]);
    cascaderRef.current?.clearValue();
  };
  const handleSetValue = () => {
    const data = [
      {
        value: "120101",
        label: "和平区",
      },
      {
        value: "120102",
        label: "河东区",
      },
    ];
    cascaderRef.current?.setValue(data.map((e) => e.value));
  };

  const open = Boolean(anchorEl);
  return (
    <>
      <div style={{ width: "500px" }}>
        <h3>多选 </h3>
        {valueAll.length ? (
          <>
            <button onClick={handleClear}>清空VALUE</button>
            <div>
              当前选中【{valueAll.map((e) => JSON.stringify(e) + ",")}】
            </div>
          </>
        ) : (
          <button onClick={handleSetValue}>设置VALUE选中</button>
        )}

        <div className="cascader">
          <div className="cascader_input_box" onClick={handleClick}>
            {valueAll.length ? (
              <div className="cascader_input">
                {valueAll.map((e) => e.label).join(" , ")}
              </div>
            ) : (
              <div className="placeholder">请选择</div>
            )}
          </div>
        </div>
      </div>

      <Cascader
        ref={cascaderRef}
        value={value}
        open={open}
        anchorEl={anchorEl}
        multiple
        options={province}
        onClose={() => setAnchorEl(null)}
        onChange={handleChange}
      />
    </>
  );
}

export default Multiple;

动态加载数据

import { useRef, useState } from "react";
import {
  Cascader,
  CascaderOption,
  CascaderRefProps,
} from "react-cascader-popover";

function Default() {
  const options = [
    {
      value: "120000",
      label: "天津市",
      isLoad: true,
    },
    {
      value: "110000",
      label: "北京市",
      disabled: true,
      isLoad: true,
    },
  ];

  const [anchorEl, setAnchorEl] = useState<HTMLDivElement | null>(null);
  const [valueAllPath, setValueAllPath] = useState<CascaderOption[]>([]);
  const [value, setValue] = useState("");
  const [num, setNum] = useState(0);
  const [valueItem, setValueItem] = useState<CascaderOption | null>(null);
  const cascaderRef = useRef<CascaderRefProps>(null);

  const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
    setAnchorEl(event.currentTarget);
  };
  const handleChange = (
    value: CascaderOption | null,
    valueAll: CascaderOption[]
  ) => {
    console.log(value, valueAll);

    setValueItem(value);
    // setValue(value ? value.value : "");
    setValueAllPath(valueAll);
  };

  // 模拟接口返回数据
  const getServiceData = (item: CascaderOption) => {
    return new Promise<CascaderOption[]>((resolve) => {
      setTimeout(() => {
        const count = num + 1;
        setNum(count);

        resolve([
          {
            label: `${item.label}-1 `,
            value: item.value + 1,
            isLoad: count >= 2 ? false : true,
          },
          {
            label: `${item.label}-2 `,
            value: item.value + 222,
            isLoad: count >= 2 ? false : true,
          },
        ]);
      }, 1000);
    });
  };

  const loadData = async (item: CascaderOption) => {
    const data = await getServiceData(item);
    return data;
  };

  const open = Boolean(anchorEl);
  return (
    <>
      <div style={{ width: "500px" }}>
        <h3>动态加载 </h3>
        <h6>value:{value}</h6>
        {valueItem ? (
          <h6>
            valueItem:{valueItem.value}/{valueItem.label}
          </h6>
        ) : (
          <></>
        )}
        {valueAllPath.length ? (
          <h6>全路径:{valueAllPath.map((e) => e.label).join(" - ")}</h6>
        ) : (
          <></>
        )}
        <div className="cascader">
          <div className="cascader_input_box" onClick={handleClick}>
            {valueAllPath.length ? (
              <div className="cascader_input">
                {valueAllPath.map((e) => e.label).join(" - ")}
              </div>
            ) : (
              <div className="placeholder">请选择</div>
            )}
          </div>
        </div>
      </div>

      <Cascader
        search
        ref={cascaderRef}
        value={value}
        open={open}
        anchorEl={anchorEl}
        options={options}
        onClose={() => setAnchorEl(null)}
        onChange={handleChange}
        loadData={loadData}
      />
    </>
  );
}

export default Default;

API

props

option

更新说明

1.0.6 更新项目

1.0.7 多选时展开列表默认展示第一个数据

1.1.0 增加输入框筛选 修复 onChange 触发问题

1.1.4 增加在多选搜索的时候可以选择多个

1.1.5 增加 loadData 动态加载数据逻辑, options 中加入禁用

1.3.3

3 days ago

1.3.2

7 days ago

1.3.1

15 days ago

1.3.0

18 days ago

1.2.9

22 days ago

1.2.8

25 days ago

1.2.7

29 days ago

1.2.6

1 month ago

1.2.5

1 month ago

1.2.4

1 month ago

1.2.3

1 month ago

1.2.2

2 months ago

1.2.0

2 months ago

1.1.9

2 months ago

1.2.1

2 months ago

1.1.8

3 months ago

1.1.7

3 months ago

1.1.6

3 months ago

1.1.5

3 months ago

1.1.4

3 months ago

1.1.3

3 months ago

1.1.1

3 months ago

1.1.0

3 months ago

1.1.2

3 months ago

1.0.9

3 months ago

1.0.8

3 months ago

1.0.7

3 months ago

1.0.6

4 months ago

1.0.5

4 months ago

1.0.4

4 months ago

1.0.3

4 months ago

1.0.2

4 months ago

1.0.1

4 months ago