当前位置: 首页 > news >正文

React+Antd实现省、市区级联下拉多选组件(支持只选省不选市)

 1、效果

是你要的效果,咱们继续往下看,搜索面板实现省市区下拉,原本有antd的Cascader组件,但是级联组件必须选到子节点,不能只选省,满足不了页面的需求

2、环境准备

1、react18

2、antd 4+

3、功能实现

原理:封装一个受控组件,该组件就是两select基本组件

1、首先,导入需要的组件:

import { Select, Space, Tag } from 'antd';

 2、定义2个状态变量来存储选中省和市的下拉枚举

  const [firstOptions, setFirstOptions] = useState<any>([]);const [secondOptions, setSecondOptions] = useState<any>([]);

 3、组件可接收的props子属性 如下:

  •  options: 省市级联数据
  •  value: 已选中的值
  •  width:slect框的宽度
  •  firstPlaceholder 第一个select框的placeholder
  • secondPlaceholder第二个select框的placeholder
  •  onChange: 选中的值发生变化时回调

 4、创建handleFirstChange函数来处理第一个select框的change事件,更新第二个select框的下拉项和值

  // 第一个select生变化const handleFirstChange = (data: any) => {if (!isEmpty(data) && data.value) {let insertIndex = (options || []).findIndex((item: any) => {return item?.value === data?.value;});setSecondOptions(options?.[insertIndex]?.children || []);onChange({ first: [data] });} else {setSecondOptions([]);onChange(null);}};

 5、创建onSecondChange 函数来处理第二个select框的change事件,将选中的值回传给父组件

  // 第二个select发生变化const onSecondChange = (data: any) => {if (!isEmpty(value) && value.first) {if (!isEmpty(data)) {onChange({...value,second: mode === 'multiple' ? (data || []).filter((item: any) => !isNil(item?.label)) : [data],});} else {onChange({ first: value.first, second: null });}} else {onChange(null);}};

 6、最后,使用2个select组件渲染,并将选中状态和change事件绑定到对应的属性上:

return (<><Space wrap={false} direction="horizontal" size={12}><SelectdefaultValue={firstOptions[0]}style={{ width: width }}onChange={handleFirstChange}placeholder={firstPlaceholder || '请选择'}value={value?.first}options={firstOptions}labelInValueallowClear/><Selectstyle={{ width: width }}value={value?.second || []}onChange={onSecondChange}placeholder={secondPlaceholder || '请选择'}options={secondOptions}{...mode === "multiple" ? { mode: "multiple", maxTagCount: 'responsive', tagRender: tagRender } : {}}labelInValueallowClear/></Space></>
)

 7、完整代码如下:

import { Select, Space, Tag } from 'antd';
import clsx from 'clsx';
import { isEmpty, isNil } from 'lodash';
import { useEffect, useState } from 'react';
import './index.less';const MultipleCascaderSelect = (props: any) => {const {options,value,onChange,width = 160,firstPlaceholder,secondPlaceholder,mode = 'multiple'} = props;const [firstOptions, setFirstOptions] = useState<any>([]);const [secondOptions, setSecondOptions] = useState<any>();useEffect(() => {setFirstOptions(options || []);if (Array.isArray(value?.first) && value.first.length) {let findIndex = (options || []).findIndex((item: any) => {return item.value === value.first?.[0].value;});setSecondOptions(options[findIndex]?.children || []);} else {setSecondOptions([]);}}, [options, value]);// 第一个select生变化const handleFirstChange = (data: any) => {if (!isEmpty(data) && data.value) {let insertIndex = (options || []).findIndex((item: any) => {return item?.value === data?.value;});setSecondOptions(options?.[insertIndex]?.children || []);onChange({ first: [data] });} else {setSecondOptions([]);onChange(null);}};// 第二个select发生变化const onSecondChange = (data: any) => {if (!isEmpty(value) && value.first) {if (!isEmpty(data)) {onChange({...value,second: mode === 'multiple' ? (data || []).filter((item: any) => !isNil(item?.label)) : [data],});} else {onChange({ first: value.first, second: null });}} else {onChange(null);}};const tagRender = ({ label, closable, onClose }: any) => {const isLongTag = `${label}`.length > 4;return (<Tagcolor={label.props?.color}closable={closable}onClose={onClose}className={clsx(['text-sky-400 bg-sky-400/10 text-sm font-normal leading-5',// 'border border-solid border-sky-400/50','max-w-[110px] border-none',// 'whitespace-nowrap text-ellipsis overflow-hidden'])}><span>{isLongTag ? `${label.slice(0, 4)}...` : label}</span>{/* {isLongTag ? (<Tooltiptitle={label}key={label}rootClassName={clsx('toolTipCard')}placement="top"><span>{label.slice(0, 4)}...</span></Tooltip>) : (<span>{label}</span>)} */}</Tag>);};return (<><Space wrap={false} direction="horizontal" size={12}><SelectdefaultValue={firstOptions[0]}style={{ width: width }}onChange={handleFirstChange}placeholder={firstPlaceholder || '请选择'}value={value?.first}options={firstOptions}labelInValueallowClear/><Selectstyle={{ width: width }}value={value?.second || []}onChange={onSecondChange}placeholder={secondPlaceholder || '请选择'}options={secondOptions}{...mode === "multiple" ? { mode: "multiple", maxTagCount: 'responsive', tagRender: tagRender } : {}}labelInValueallowClear/></Space></>);
};export default MultipleCascaderSelect;

组件调用

 <MultipleCascaderSelectwidth={162}options={enumData|| []}firstPlaceholder="请选择"secondPlaceholder="请选择"/>

相关文章:

React+Antd实现省、市区级联下拉多选组件(支持只选省不选市)

1、效果 是你要的效果&#xff0c;咱们继续往下看&#xff0c;搜索面板实现省市区下拉&#xff0c;原本有antd的Cascader组件&#xff0c;但是级联组件必须选到子节点&#xff0c;不能只选省&#xff0c;满足不了页面的需求 2、环境准备 1、react18 2、antd 4 3、功能实现 …...

CentOS镜像如何下载?在VMware中如何安装?

一、问题 CentOS镜像如何下载&#xff1f;在VMware中如何安装&#xff1f; 二、解决 1、CentOS镜像的下载 &#xff08;1&#xff09;官方网站 The CentOS Project &#xff08;2&#xff09;官方中文官网 CentOS 中文 官网 &#xff08;3&#xff09;选择CentOS Linux…...

计算机科学导论(4)DMA传输原理

文章目录 DMA的工作原理DMA的优势DMA的类型DMA的应用 DMA&#xff08;Direct Memory Access&#xff09;直接内存访问是一种允许某些硬件子系统在不通过中央处理单元&#xff08;CPU&#xff09;的情况下&#xff0c;直接从内存读取或向内存写入数据的技术。这种方式可以显著提…...

select、poll和epoll的区别

文章目录 概要一、多路复用I/O模型的诞生1.1 多线程或进程方式1.2 通过数组&#xff0c;链表等方式保存socket fd&#xff0c;不断轮询 二、select三、poll四、epoll五、小结六、参考 概要 在Unix五种I/O模型一文中&#xff0c;提到了I/O多路复用模型&#xff0c;其在Linux下有…...

gpt今日最新新闻:gpts的广泛应用

最近&#xff0c;OpenAI给ChatGPT带来了一个备受期待的更新——“GPT提及&#xff08;mentions&#xff09;”功能。这项创新不仅增强了ChatGPT的实用性&#xff0c;也为AI在日常业务中的运用开辟了新路径。在本文中&#xff0c;我将分享我对这项新功能的初步体验&#xff0c;并…...

【进入游戏行业选游戏特效还是技术美术?】

进入游戏行业选游戏特效还是技术美术&#xff1f; 游戏行业正处于蓬勃发展的黄金时期&#xff0c;科技的进步推动了游戏技术和视觉艺术的飞速革新。在这个创意和技术挑战交织的领域里&#xff0c;游戏特效和技术美术岗位成为了许多人追求的职业目标。 这两个岗位虽然紧密关联…...

(delphi11最新学习资料) Object Pascal 学习笔记---第4章第2.3节(常量参数)

4.2.3 常量参数 ​ 作为引用参数的替代&#xff0c;您可以使用const参数。由于您无法在例程内为const参数赋予新值&#xff0c;因此编译器可以优化参数传递。编译器可以选择与引用参数相似的方法&#xff08;或者在C术语中是const引用&#xff09;&#xff0c;但行为类似于值参…...

事件在状态流程图中的工作方式

什么是事件&#xff1f; 事件是一个Stateflow对象&#xff0c;它可以触发以下对象中一个动作&#xff1a; Simulink触发子系统 Simulink函数调用子系统 状态流程图 何时使用事件 当你想&#xff1a; 激活Simulink触发的子系统 激活Simulink函数调用子系统 在状态流程图…...

幻兽帕鲁能在Mac上运行吗?幻兽帕鲁Palworld新手攻略

幻兽帕鲁能在Mac上运行吗&#xff1f; 《幻兽帕鲁》目前还未正式登陆Mac平台&#xff0c;不过通过一些方法是可以让游戏在该平台运行的。 虽然游戏不能在最高配置下运行&#xff0c;但如果你安装了CrossOver这个软件&#xff0c;就可以玩了。这是为Mac、Linux和ChromeOS等设计…...

elementPlus实现动态表格单元格合并span-method方法总结

最近在做PC端需求的时候&#xff0c;需要把首列中相邻的同名称单元格合并。 我看了一下elementPlus官网中的table表格&#xff0c;span-method可以实现单元格合并。 我们先看一下官网的例子&#xff1a; 合并行或列 多行或多列共用一个数据时&#xff0c;可以合并行或列。 …...

视频上传 - 断点续传那点事

在上一篇文章中&#xff0c;我们讲解了分片上传的实现方式。在讲解断点续传之前&#xff0c;我要把上篇文章中留下的问题讲解一下。读过上一篇文章的小伙伴们都知道&#xff0c;对于分片上传来说&#xff0c;它的传输方式分为2种&#xff0c;一种是按顺序传输&#xff0c;一种是…...

Scala 和 Java在继承机制方面的区别

Scala 和 Java 都是面向对象编程语言&#xff0c;都支持类的继承机制。然而&#xff0c;尽管两者在基础概念上有很多相似之处&#xff0c;但在具体的实现和语法上&#xff0c;Scala 的继承机制有其独特之处。以下是 Scala 和 Java 在继承方面的一些主要区别&#xff1a; 多重继…...

spark sql上线前的调试工作实现

背景 每个公司应该都有大数据的平台的吧&#xff0c;平台的作用就是可以在上面执行各种spark sql以及定时任务&#xff0c;不过一般来说&#xff0c;由于这些spark sql的上线不经过测试&#xff0c;所以可能会影响到生产的数据&#xff0c;这种情况下大数据平台提供一个上线前…...

java -jar启动SpringBoot项目时配置文件加载位置与优先级

服务部署启动时,我们经常需要指定配置文件启动. 一般有四种,优先级如下 spring.config.location > spring.profiles.active > spring.config.additional-location > 默认的 application.yml 1.spring.config.location 外部配置文件优先级最高 一般配置文件在服务…...

每日一题 力扣LCP30.魔塔游戏

题目描述&#xff1a; 小扣当前位于魔塔游戏第一层&#xff0c;共有 N 个房间&#xff0c;编号为 0 ~ N-1。每个房间的补血道具/怪物对于血量影响记于数组 nums&#xff0c;其中正数表示道具补血数值&#xff0c;即血量增加对应数值&#xff1b;负数表示怪物造成伤害值&#x…...

iPhone搞机记录

-iPhone 8 或以上 设备进入DFU模式的方法&#xff1a; &#xff08;适用&#xff1a;iPhone 8/8 Plus、iPhone X 系列、iPad Pro3 (11-inch)/(12.9-inch)&#xff09; 1.保持设备处于开机或恢复模式下&#xff0c;插入数据线。 2.按一次设备的“音量加键”松开、再按一次“音量…...

Linux中共享内存(mmap函数的使用)

内存映射的基本使用 内存映射 概念&#xff1a; 使一个磁盘文件与内存中的一个缓冲区相映射&#xff0c;进程可以像访问普通内存一样对文件进行访问&#xff0c;不必再调用read,write。 mmap()的优点&#xff1a; 实现了用户空间和内核空间的高效交互方式 优化前&#xff1a;优…...

Golang与Erlang有什么差异

Golang和Erlang是两种备受关注的编程语言&#xff0c;它们各自具有独特的特点和优势。下面我将简单的探讨一下Golang和Erlang之间的差异&#xff0c;并且分析它们在并发模型、运行环境、函数式编程和领域特性等多个方面的不同之处。 并发模型 Golang使用goroutines和channels…...

cesium系列篇:Entity vs Primitive 源码解析(从Entity到Primitive)02

上篇文章中&#xff0c;我们介绍了使用viewer.entities.add添加entity之后的信号传递以及最后entity对象被传递到GeometryVisualizer&#xff1b; 这篇文章&#xff0c;我们则介绍如何在逐帧渲染的过程中根据GeometryVisualizer中的entity对象创建相应的primitive 这是下文中…...

golang windows 环境搭建 环境配置

golang windows 环境搭建 环境配置 Golang学习之路一环境搭建 MacBook Linux 树莓派raspberrypi安装Golang环境 官网下载地址: https://go.dev/dl/ https://golang.google.cn/dl/ 下载对应系统版本&#xff0c;例如windows 64位系统&#xff0c;下载&#xff1a;xxx.window…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...