react级联选择器/支持多选/单选
npm install react-cascader-popoverbash
npm i react-cascader-popover
或者
yarn add react-cascader-popover
`
demo
https://react-cascader-popover-eyrp.vercel.app/
单选

`js
import { useRef, useState } from "react";
import { province } from "../data";
import {
Cascader,
CascaderOption,
CascaderRefProps,
} from "react-cascader-popover";
function Default() {
const [anchorEl, setAnchorEl] = useState(null);
const [valueAllPath, setValueAllPath] = useState([]);
const [value, setValue] = useState("120103");
const cascaderRef = useRef(null);
// 点击展开
const handleClick = (event: React.MouseEvent) => {
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 (
<>
{valueAllPath.length ? (
{valueAllPath.map((e) => e.label).join(" - ")}
) : (
请选择
)}
ref={cascaderRef}
value={value}
open={open}
anchorEl={anchorEl}
options={province}
onClose={() => setAnchorEl(null)}
onChange={handleChange}
/>
>
);
}
export default Default;
`
多选

`js
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(null);
const [valueAll, setValueAll] = useState([]);
const cascaderRef = useRef(null);
const handleClick = (event: React.MouseEvent) => {
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 (
<>
多选
{valueAll.length ? (
<>
当前选中【{valueAll.map((e) => JSON.stringify(e) + ",")}】
>
) : (
)}
{valueAll.length ? (
{valueAll.map((e) => e.label).join(" , ")}
) : (
请选择
)}
ref={cascaderRef}
value={value}
open={open}
anchorEl={anchorEl}
multiple
options={province}
onClose={() => setAnchorEl(null)}
onChange={handleChange}
/>
>
);
}
export default Multiple;
`
动态加载数据
`js
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(null);
const [valueAllPath, setValueAllPath] = useState([]);
const [value, setValue] = useState("");
const [num, setNum] = useState(0);
const [valueItem, setValueItem] = useState(null);
const cascaderRef = useRef(null);
const handleClick = (event: React.MouseEvent) => {
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((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 (
<>
动态加载
value:{value}
{valueItem ? (
valueItem:{valueItem.value}/{valueItem.label}
) : (
<>>
)}
{valueAllPath.length ? (
全路径:{valueAllPath.map((e) => e.label).join(" - ")}
) : (
<>>
)}
{valueAllPath.length ? (
{valueAllPath.map((e) => e.label).join(" - ")}
) : (
请选择
)}
search
ref={cascaderRef}
value={value}
open={open}
anchorEl={anchorEl}
options={options}
onClose={() => setAnchorEl(null)}
onChange={handleChange}
loadData={loadData}
/>
>
);
}
export default Default;
``
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| value | string | 选中的值 | |
| options | CascaderOption[] | [] | 数据 |
| open | boolean | false | 是否弹出选择器 |
| anchorEl | HTMLDivElement | null | null | HTMLDivElement元素 用于展示窗口的位置 |
| multiple | boolean | false | 是否开启多选 |
| search | boolean | false | 是否开启搜索 |
| searchEmptyText | string | 暂无数据 | 搜索为空提示 |
| searchPlaceholder | string | 请输入关键词 | 搜索框提示语 |
| loadData | (value: CascaderOption) => Promise<CascaderOption[]> | 动态加载数据 options中要存在isLoad 配合 async await 使用 | |
| onChange | (value: CascaderOption | null, valueAll: CascaderOption[]) => void | 点击后的事件 | |
| onClose | () => void | 隐藏选择器事件 | |
| ref | CascaderRefProps |
setValue: (value: string[]) => void;
clearValue: () => void;
用于多选时使用 |
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| label | string | 展示的文字 | |
| value | string | 对应的value | |
| disabled | boolean | false | 禁用 |
| isLoad | boolean | false | true=有下级数据 |
| children | Array | children |