React+TS前台项目实战(七)-- 全局常用组件Select封装

文章目录

  • 前言
  • Select组件
    • 1. 功能分析
    • 2. 代码+详细注释说明
    • 3. 使用方式
    • 4. 效果展示
    • (1)鼠标移入效果
    • (2)下拉框打开效果
    • (3)回调输出
  • 总结


前言

今天这篇主要讲全局select组件封装,可根据UI设计师要求自定义修改。


Select组件

1. 功能分析

(1)鼠标移入,选中时,选择框样式处理
(2)定义Option和props的类型,用于表示组件的相关属性
(3)添加onChange属性,用于定义选中选项时的回调函数
(4)添加defaultValue属性,用于定义默认选中的选项
(5)添加placeholder属性,用于定义选项为空时的占位符文本
(6)添加className属性,用于定义组件的自定义类名
(7)使用react-outside-click-handler插件,实现点击外部区域时收起下拉框的功能

2. 代码+详细注释说明

// @/components/Select/index.tsx
import { useState, FC } from "react";
import OutsideClickHandler from "react-outside-click-handler";
import classNames from "classnames";
import styles from "./index.module.scss";
import Arrow from "@/assets/arrowDown.png";
// 定义Option的类型,用于表示选项的属性
type Option = {label: string; // 选项的显示文本value: string; // 选项的值
};// 定义Props的类型,用于表示组件的属性
type Props = {options: Option[]; // 选项数组onChange: (value: string) => void; // 选中选项时的回调函数defaultValue?: string; // 默认选中的选项值placeholder?: string; // 选项为空时的占位符文本className?: string; // 组件的自定义类名
};// 定义Select的组件,用于实现下拉选择框的功能
const Select: FC<Props> = (props) => {// 解构组件的属性const { options, onChange, defaultValue, placeholder, className } = props;// 获取默认选中的选项的显示文本const defaultLabel = options.find((option) => option.value === defaultValue)?.label;// 定义状态变量const [isExpanded, setIsExpanded] = useState(false); // 是否展开下拉框const [value, setValue] = useState(defaultLabel); // 当前选中的选项的显示文本const [currentIndex, setCurrentIndex] = useState(1); // 当前选中的选项的索引// 切换下拉框的展开状态const toggleExpand = () => {setIsExpanded(!isExpanded);};// option选项点击事件const handlerOptionClick = (option: Option, index: number) => {setValue(option.label); // 更新当前选中的选项的显示文本onChange(option.value); // 调用回调函数,通知父组件选中的选项值setCurrentIndex(index); // 更新当前选中的选项的索引toggleExpand(); // 切换下拉框的展开状态};return (// 使用OutsideClickHandler组件包裹根元素,用于处理点击外部区域的事件<OutsideClickHandler onOutsideClick={() => setIsExpanded(false)}><div className={classNames(styles.outsideContainer, className)}><div className={classNames(styles.selectContainer, isExpanded && styles.isFocused)} onClick={toggleExpand}><div className={classNames(styles.selectValue)}><div className={classNames(styles.selectText)}>{value ?? placeholder}</div></div><img src={Arrow} alt="" data-is-flipped={isExpanded} /></div>{isExpanded && (// 如果下拉框展开,则渲染选项列表<ul className={classNames(styles.selectOption)}>{options.map((option, index) => (<li className={classNames(styles.selectOptionItem, index === currentIndex && styles.selected)} key={option.value} onClick={() => handlerOptionClick(option, index)}><span className={classNames(styles.optionValue)}>{option.label}</span></li>))}</ul>)}</div></OutsideClickHandler>);
};export default Select;
------------------------------------------------------------------------------
// @/components/Button/index.module.scss
.outsideContainer {position: relative;
}.selectContainer {display: flex;align-items: center;justify-content: space-between;padding: 8px 16px;min-height: 40px;border-radius: var(--cd-border-radius-base);background-color: var(--cd-fill-color-blank);transition: var(--cd-transition-duration);box-shadow: 0 0 0 1px var(--cd-border-color);cursor: pointer;user-select: none;position: relative;&.isFocused {box-shadow: 0 0 0 1px var(--cd-shadow-color) inset;}&:hover:not(.isFocused) {box-shadow: 0 0 0 1px var(--cd-border-color-hover) inset;}.selectValue {display: flex;flex-wrap: wrap;align-items: center;flex: 1;min-width: 0;position: relative;.selectText {position: absolute;top: 50%;transform: translateY(-50%);width: 100%;text-align: left;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}}img {width: 10px;transform: rotate(0);transition: var(--cd-transition-duration);&[data-is-flipped="true"] {transform: rotateX(180deg);}}
}
.selectOption {min-width: fill-available;padding: 6px 0;margin-top: 5px;border-radius: 4px;list-style: none;background-color: #ffffff;border: 1px solid #e4e7ed;box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);position: absolute;.selectOptionItem {font-size: 14px;padding: 0 20px;position: relative;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;color: #606266;height: 34px;line-height: 34px;box-sizing: border-box;cursor: pointer;&:hover {background-color: #f5f7fa;}&.selected {color: var(--cd-shadow-color);}}
}

3. 使用方式

import { useState } from "react";
// 引入组件
import Select from "@/components/Select";
// 使用方式
const [options] = useState([{label: "标签1",value: "123",},{label: "标签2",value: "456",},
]);
const defaltValue = options[1].value
<Select options={options} onChange={onChange} defaultValue={defaltValue} placeholder="请选择"></Select>// 选择变化
const onChange = (value: string) => {console.log("onChange", value);
};

4. 效果展示

(1)鼠标移入效果

在这里插入图片描述

(2)下拉框打开效果

在这里插入图片描述

(3)回调输出

在这里插入图片描述


总结

下一篇讲【全局常用组件模态框Modal封装】。关注本栏目,将实时更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/27879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络通信的两大支柱:TCP与UDP协议详解(非常详细)零基础入门到精通,收藏这一篇就够了

在构建现代互联网通信的基石中&#xff0c;TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;起着至关重要的作用。本文将深入探讨两者的区别及应用场景。 1 TCP和UDP的共同点 传输层协议&#xff1a; TCP和UDP都是传输层协议&#xff…

紫光展锐5G处理器T750__国产手机芯片5G方案

展锐T750核心板采用6nm EUV制程工艺&#xff0c;CPU架构采用了八核设计&#xff0c;其中包括两个主频为2.0GHz的Arm Cortex-A76性能核心和六个主频为1.8GHz的A55小核。这种组合使得T750具备卓越的处理能力&#xff0c;并能在节能的同时提供出色的性能表现。该核心模块还搭载了M…

L51--- 144. 二叉树的前序遍历(深搜)---Java版

1.题目描述 2.思路 二叉树的前序遍历遵循 根左右 &#xff08;1&#xff09;方法 preorderTraversal 输入参数: TreeNode root root是二叉树的根节点。 返回值: List 返回一个包含二叉树节点值的列表&#xff0c;这些值按照前序遍历的顺序排列。 功能: 这个方法是前序遍历的…

微信小程序04: 获取openId和unionId

全文目录,一步到位 1.前言简介1.1 专栏传送门1.1.1 上文小总结1.1.2 上文传送门 2. 获取openId和unionId操作2.1 准备工作2.1.1 请先复制00篇的统一封装代码2.1.2 微信登录请求dto 2.2 具体代码使用与注释如下2.2.1 业务代码2.2.2 代码解释(一)[无需复制]2.2.3 获取的map使用方…

值传递和址传递

值传递 上面的代码是想要交换x&#xff0c;y的值&#xff0c;把x&#xff0c;y传递给swap函数之后&#xff0c;执行下面的操作&#xff1a; 在swap中a和b交换了&#xff0c;但是和x&#xff0c;y没有关系&#xff0c;所以x&#xff0c;y在main中不会变。 址传递 下面再看把x…

2024FIC决赛

容器密码&#xff1a;2024Fic~Competition~Finals杭州&Powered~By~HL! 案件背景: 2023年3月15日凌晨,受害人短视频平台上看到一段近期火爆的交通事故视频&#xff0c;留言后有人通过私信联系&#xff0c;称有一个赚大钱的机会&#xff0c;该人自称李某&#xff0c;提议让…

软件工程期末复习题

目录 选择 判断 选择 下列说法中正确的是 ( B )。 A、20 世纪50 年代提出了软件工程的概念摇 B、20 世纪60 年代提出了软件工程的概念 C、20 世纪70 年代出现了客户端/ 服务器技术 D、20 世纪80 年代软件工程学科达到成熟 软件危机的主要原因是 ( D )。 A、软件工具落后…

基于STM32移植U8g2图形库——OLED显示(HAL库)

文章目录 一、U8g2简介1、特点2、U8g2的使用步骤 二、I2C相关介绍1、I2C的基本原理2、I2C的时序协议 三、OLED屏的工作原理四、汉字点阵显示原理五、建立STM32CubeMX工程六、U8g2移植1、U8g2源码2、移植过程 七、代码编写1、参考博主实现的U82G的demo例程&#xff08;1&#xf…

【Linux内核】伙伴系统算法和slab分配器(1)

【Linux内核】伙伴系统算法和slab分配器&#xff08;1&#xff09; 目录 【Linux内核】伙伴系统算法和slab分配器&#xff08;1&#xff09;伙伴系统&#xff08;buddy&#xff09;算法伙伴系统算法基本原理内存申请内存回收 接口函数源码分析内存分配接口物理内存释放接口规范…

基于Wireshark实现对FTP的抓包分析

基于Wireshark实现对FTP的抓包分析 前言一、虚拟机Win10环境配置二、FileZilla客户端的安装配置下载FileZilla客户端安装FileZilla 三、FileZilla Server安装下载FileZilla Server安装 四、实现对FTP的抓包前置工作实现抓包完成抓包 前言 推荐一个网站给想要了解或者学习人工智…

Setapp:只需一次订阅,即可获得 240 款+ Mac 软件

为一项任务寻找合适的应用程序是一项相当艰巨的任务。过去&#xff0c;最好的办法要么是花费宝贵的时间搜索可靠的评论&#xff0c;要么就是相信无论安装什么软件都能完成任务。 如果你是 Mac 用户&#xff0c;那么 Setapp 将让这一问题成为过去。无需在需要时下载单个程序&am…

vue之一键部署的shell脚本和它的点.bat文件、海螺AI、ChatGPT

MENU 前言vite.config.ts的配置deploy文件夹的其他内容remote.shpwd.txtdeploy.bat 前言 1、在src同级新建deploy.bat文件&#xff1b; 2、在src同级新建deploy文件夹&#xff0c;文件夹中新建pwd.txt和remote.sh文件&#xff1b; 3、配置好后&#xff0c;直接双击deploy.bat文…

鸿蒙轻内核M核源码分析系列二一 02 文件系统LittleFS

1、LFS文件系统结构体介绍 会分2部分来介绍结构体部分&#xff0c;先介绍LittleFS文件系统的结构体&#xff0c;然后介绍LiteOS-M内核中提供的和LittleFS相关的一些结构体。 1.1 LittleFS的枚举结构体 在openharmony/third_party/littlefs/lfs.h头文件中定义LittleFS的枚举、…

在线时钟python案例

试了一下用通义来编写一些代码&#xff0c;以下是一个在线时钟的样例&#xff0c;只要能运行python就可以使用。 以下是运行后的结果。 代码&#xff08;复制可用&#xff09; import tkinter as tk from time import strftimedef update_time():current_time strftime(&quo…

Postman使用教程(Postman详细图文教程)

本文讲解的是postman工具安装、postman安装教程、postman工具下载、postman使用教程。Postman使得得开发人员和测试人员能够更高效地与Web服务进行交互和调试。 Postman不仅支持常见的HTTP方法&#xff0c;如GET、POST、PUT、DELETE等&#xff0c;还提供了丰富的请求编辑功能&…

20240615给飞凌的OK3588-C开发板刷Rockchip原厂的Buildroot后的测试报告

20240615给飞凌的OK3588-C开发板刷Rockchip原厂的Buildroot后的测试报告&#xff1a; 【切记&#xff0c;由于没有替换DTS的&#xff0c;开发板发热量巨大&#xff01;因此配备鼓风机进行加强散热了】 0、adb 默认没有 1、HDMI IN 4K 2024/6/15 20:32 4K全屏 2、HDMI OUT …

Redis原理篇——分布式锁

Redis原理篇——分布式锁 分布式锁是什么&#xff1f;分布式锁有哪些特性&#xff1f;分布式锁常用实现方式Redis 实现分布式锁一、简单的 Redis 锁二、带过期时间的 Redis 锁三、加上 Owner 的 Redis 锁四、Lua 脚本确保原子性 分布式锁是什么&#xff1f; 分布式锁是在分布式…

软件体系结构笔记(自用)

来自《软件体系结构原理、方法与实践&#xff08;第三版&#xff09;》清华大学出版社 张友生编著 1-8章12章 复习笔记 如有错误&#xff0c;欢迎指正&#xff01;&#xff01;&#xff01;

HCIP认证笔记(填空)

1、为防止攻击者伪造BGP报文对设备进行攻击,可以通过配置GTSM功能检测IP报文中的TTL值的范围来对设备进行保护。如果某台设备配置了“peer x.x.x.x valid-ttl-hops 100",则被检测的报文的TTL值的有效范围为【(156),255】; 解析: peer {group-name | ipv4-address…

学习cel-go了解一下通用表达语言评估是什么

文章目录 1. 前言2. cel-go2.1 cel-go关键概念Applications(应用)Compilation(编译)Expressions(表达式)Environment环境解析表达式的三个阶段 3. cel-go的使用4. cel-go使用5. 说明6. 小结7. 参考 1. 前言 最近因为在项目里面实现的一个使用和||来组合获取字段值的功能有点儿…