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

React+TS前台项目实战(十九)-- 全局常用组件封装:带加载状态和清除等功能的Input组件实现

文章目录

  • 前言
  • Input组件
    • 1. 功能分析
    • 2. 代码+详细注释
    • 3. 使用方式
    • 4. 效果展示
  • 总结


前言

今天我们来封装一个input输入框组件,并提供一些常用的功能,你可以选择不同的 尺寸添加前缀显示加载状态触发回调函数自定义样式 等等。这些功能在这个项目中已经足够了,无论你是一个经验丰富的开发者还是一个刚刚入门的新手,这篇文章都将提供有用的知识和实践经验,以帮助你在自己项目中封装输入框时更加高效


Input组件

1. 功能分析

(1)通过传入loading加载状态属性,当激活时会显示加载图标
(2)通过传入size属性, 可以有不同的大小:“default”、“small” 或 “large”
(3)提供onChange值发生变化回调函数;失去焦点onBlur回调函数;键盘回车onKeyUp回调函数;
(4)当输入框有值时,组件会显示一个清除按钮,用户可以通过点击按钮来清除输入框的值
(5)通过传入className属性, 可以自定义输入框的样式
(6)通过 elprops 属性将其他属性传递给底层的 input 元素

2. 代码+详细注释

// @/components/Input/index.tsx
import { FC, ReactNode, useCallback, useState, ChangeEventHandler, FocusEvent, ComponentPropsWithoutRef, KeyboardEventHandler } from "react";
import classNames from "classnames";
import { InputContainer } from "./styled";
import { ReactComponent as SearchIcon } from "./assets/search.svg";
import { ReactComponent as LoadingIcon } from "./assets/loading.svg";
import { ReactComponent as ClearIcon } from "./assets/clear.svg";
import SimpleButton from "@/components/SimpleButton";// 组件的属性类型
type Props = Omit<ComponentPropsWithoutRef<"input">, "size"> & {// 按下回车的回调onEnter?: () => void;// 是否显示加载状态loading?: boolean;// 输入框大小size?: "default" | "small" | "large" | undefined;// 输入框前缀prefix?: boolean | ReactNode;
};// 输入框组件
const Input: FC<Props> = ({ loading, size, onEnter, value: propsValue, onChange: propsOnChange, onKeyUp: propsOnKeyUp, onBlur: propsOnBlur, className, ...elprops }) => {// 输入框的值,通过状态管理const [value, setValue] = useState(propsValue);// 输入事件const handlerChange: ChangeEventHandler<HTMLInputElement> = useCallback((event) => {// 如果正在加载,直接返回if (loading) {return;}// 更新状态和回调setValue(event.target.value);propsOnChange?.(event);},[propsOnChange, setValue, loading]);// 回车事件const onKeyUp: KeyboardEventHandler<HTMLInputElement> = useCallback((event) => {// 如果是回车键,触发回调const isEnter = event.keyCode === 13;if (isEnter) {onEnter?.();}propsOnKeyUp?.(event);},[onEnter, propsOnKeyUp]);// 失去焦点事件const onBlur = useCallback((event: FocusEvent<HTMLInputElement>) => {propsOnBlur?.(event);},[propsOnBlur]);return (<InputContainer className={classNames(className)} size={size}>{/* 加载状态图标 */}{loading ? <LoadingIcon className={classNames("input-loading-icon")} /> : <SearchIcon className={classNames("input-search-icon")} />}{/* 输入框 */}<input enterKeyHint="search" value={value} onChange={handlerChange} onKeyUp={onKeyUp} onBlur={onBlur} {...elprops} />{/* 清除按钮 */}{value && (<SimpleButton className={classNames("input-clear-icon")} title="clear" onClick={() => setValue("")}><ClearIcon /></SimpleButton>)}</InputContainer>);
};export default Input;
------------------------------------------------------------------------------
// @/components/Input/styled.tsx
import styled from "styled-components";
import variables from "@/styles/variables.module.scss";
type InputProps = {size: "default" | "small" | "large" | undefined;
};
export const InputContainer = styled.div<InputProps>`@keyframes rotate {100% {transform: rotate(360deg);}}position: relative;margin: 0 auto;width: 100%;height: ${({ size }) => {if (size === "default") return "var(--cd-input-height)";else if (size === "small") return "var(--cd-input-sm-height)";else return "var(--cd-input-large-height)";}};padding-right: 8px;display: flex;align-items: center;justify-content: center;background: white;border: 0 solid white;border-radius: 4px;input {position: relative;width: 100%;height: 100%;font-size: 14px;padding: 0 8px;background: #fff;color: #333;border: 0 solid #fff;border-radius: 5px;&:focus {color: #333;outline: none;}&::placeholder {color: #888;}@media (max-width: ${variables.mobileBreakPoint}) {font-size: 12px;width: 100%;padding-left: 6px;padding-right: 16px;}}.input-loading-icon,.input-search-icon {flex-shrink: 0;width: 20px;height: 20px;margin-left: 8px;}.input-loading-icon {animation: rotate 2s linear infinite;}.input-clear-icon {display: flex;align-items: center;flex-shrink: 0;}
`;

3. 使用方式

// 引入组件
import Input from '@/components/Input'
// 使用
const [loading, setLoading] = useState(false);
const [searchkeyword, setSearchkeyword] = useState("");
{/* 输入框值变化回调事件 */}
const onInputChange: ChangeEventHandler<HTMLInputElement> = (event) => {console.log("onInputChange", event.target.value);setSearchkeyword(event.target.value);
};
{/* 失焦回调事件 */}
const onInputBlur = () => {};
{/* 小尺寸,不带loading */}
<Input placeholder="请输入" size="small" />
{/* 标准尺寸,带loading */}
<Input placeholder="请输入" loading={loading} onChange={onInputChange} onBlur={onInputBlur} />
{/* 大尺寸,不带loading */}
<Input placeholder="请输入" size="large" />
{/* 带前缀 */}
<Input hasPrefix placeholder="请输入" loading={loading}} />
{/* 不带前缀 */}
<Input placeholder="请输入" loading={loading} onChange={onInputChange} onBlur={onInputBlur} />

4. 效果展示

(1)输入后,加载效果如下
注:如请求数据时添加加载状态,请求结束后取消加载状态

在这里插入图片描述

(2)点击清除按钮,清除数据效果

在这里插入图片描述

(3)三种尺寸显示如下

在这里插入图片描述
(4)带前缀 / 不带前缀效果
在这里插入图片描述


总结

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

相关文章:

React+TS前台项目实战(十九)-- 全局常用组件封装:带加载状态和清除等功能的Input组件实现

文章目录 前言Input组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天我们来封装一个input输入框组件&#xff0c;并提供一些常用的功能&#xff0c;你可以选择不同的 尺寸、添加前缀、显示加载状态、触发回调函数、自定义样式 等等。这些功能在这个项目中…...

php composer 报错

引用文章&#xff1a; Composer设置国内镜像_composer 国内源-CSDN博客 php composer.phar require --prefer-dist yiidoc/yii2-redactor "*" A connection timeout was encountered. If you intend to run Composer without connecting to the internet, run the …...

数据安全如何防护?迅软加密软件保护企业数据资产

前言&#xff1a;加密软件是一种重要的工具&#xff0c;可以帮助企业保护其数据资产的安全。通过使用加密算法&#xff0c;加密软件可以将敏感数据转化为无法理解的密文&#xff0c;只有授权的用户才能解密并访问这些数据。 一、迅软加密软件保护企业数据资产的关键方面 1、数…...

Android 11 ,默认授予预置应用/APK 需要的权限,解决permission denied for window type 2003 问题。

写这篇文章的原因是解决了一个APP闪退的问题&#xff0c;闪退的原因是插拔U盘时&#xff0c;注册的广播接收者接收到广播需要弹出一个Dialog询问是否需要打开U盘&#xff0c;这个Dialog设置的是系统级别悬浮窗&#xff0c;没有这个权限&#xff0c;报错导致闪退&#xff0c;下面…...

RabbitMQ(消息队列)

RabbitMQ 它是消息中间件&#xff0c;是在消息的传输过程中保存消息的容器&#xff0c;实现应用程序和应用程序之间通信的中间产品。目前主流消息队列通讯协议是AMQP&#xff08;二进制传输&#xff0c;支持多种语言&#xff09;、JMS&#xff08;HTTP传输&#xff0c;只支持J…...

LeetCode-数组/回溯-No40组合总和II

题目&#xff1a; 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次 。 注意&#xff1a;解集不能包含重复的组合。 示例 1: 输入: ca…...

直接调用 Java 线程的 run() 方法会发生什么?

文章目录 前言回顾run() 方法 vs start() 方法run()方法start()方法 直接调用 run() 方法的影响直接调用 run() 方法调用 start() 方法 示例解析结论个人简介 前言 在Java中&#xff0c;多线程编程是一个重要的概念&#xff0c;尤其是在处理并发任务时。线程是Java中实现多线程…...

计算机毕业设计Thinkphp/Laravel学生考勤管理系统zyoqy

管理员登录学生考勤管理系统后&#xff0c;可以对首页、个人中心、公告信息管理、年级管理、专业管理、班级管理、学生管理、教师管理、课程信息管理、学生选课管理、课程签到管理、请假申请管理、销假申请管理等功能进行相应操作&#xff0c;如图5-2所示。学生登录进入学生考勤…...

3浏览器安全

上一篇&#x1f449;: 浏览器渲染原理 浏览器安全涉及多方面的威胁与防护&#xff0c;其中XSS&#xff08;跨站脚本攻击&#xff09;与CSRF&#xff08;跨站请求伪造&#xff09;是最常见的两类安全问题&#xff0c;而中间人攻击与网络劫持也是不容忽视的安全隐患。下面是对这…...

昇思25天学习打卡Day01

实验结果 心得体会 趁着假期&#xff0c;跟谁官方实战营开始系统学习MindSpore深度学习框架。昇思MindSpore是一个全场景深度学习框架&#xff0c;旨在实现易开发、高效执行、全场景统一部署三大目标。其中易开发表现为API友好&#xff0c;调试难度低&#xff1b;高效执行包括…...

Python-爬虫 下载天涯论坛帖子

为了爬取的高效性&#xff0c;实现的过程中我利用了python的threading模块&#xff0c;下面是threads.py模块&#xff0c;定义了下载解析页面的线程&#xff0c;下载图片的线程以及线程池 import threading import urllib2 import Queue import re thread_lock threading.RL…...

创建github个人博客

文章目录 安装Hexo安装git安装Node.js安装 Hexo git配置SSH key配置ssh 搭建个人博客新建博客生成静态网页 本文主要参考 【保姆级】利用Github搭建自己的个人博客&#xff0c;看完就会 安装Hexo 参考官方文档&#xff1a;https://hexo.io/zh-cn/docs/ Hexo 是一个快速、简洁且…...

【五子棋game】

编写一个五子棋游戏程序可以分为几个步骤&#xff1a;设计棋盘、定义规则、实现人机交互、判断胜负。下面是一个简化的五子棋游戏程序示例&#xff0c;使用Python语言编写。 首先&#xff0c;我们需要一个棋盘。可以使用一个二维数组来表示棋盘&#xff0c;其中0表示空位&#…...

从入门到精通:使用Python的Watchdog库监控文件系统的全面指南

从入门到精通&#xff1a;使用Python的Watchdog库监控文件系统的全面指南 引言Watchdog库概述核心组件工作原理 快速开始&#xff1a;设置Watchdog安装Watchdog创建一个简单的监控脚本设置和启动Observer 事件处理&#xff1a;如何响应文件系统的变化基本事件处理处理复杂的场景…...

Linux 进程管理指令

Linux 进程管理是系统管理的重要部分&#xff0c;通过各种工具和命令&#xff0c;你可以查看、控制、调试和管理进程。以下是一些常用的 Linux 进程管理命令和工具。 查看进程 1. ps ps 命令用于列出当前系统的进程。 查看当前用户的所有进程&#xff1a; ps -u $USER查看…...

Java OA系统通知公告模块

### 使用Spring Boot实现OA通知公告模块 使用Spring Boot框架实现一个支持多种形式公告发布、设置发布时间和有效期&#xff0c;以及公告发布后推送通知的模块。 #### 项目结构 结构组织项目&#xff1a; OA_Notification_Module/ ├── src/ │ ├── main/ │ │ …...

简约的服务器监控工具Ward

什么是 Ward &#xff1f; Ward 是一个简单简约的服务器监控工具。 Ward 支持自适应设计系统。此外&#xff0c;它还支持深色主题。它仅显示主要信息&#xff0c;如果您想查看漂亮的仪表板而不是查看一堆数字和图表&#xff0c;则可以使用它。 Ward 在所有流行的操作系统上都能…...

新能源发电乙级资质所需办理标准

企业资历与信誉&#xff1a; 必须具有独立企业法人资格。社会信誉良好&#xff0c;注册资本不少于100万元人民币。 技术条件&#xff1a; 专业技术人员配置齐全、合理&#xff0c;数量需满足资质标准要求。主要技术负责人或总工程师应具有大学本科以上学历、10年以上设计经历&a…...

Elasticsearch:使用 Llamaindex 的 RAG 与 Elastic 和 Llama3

这篇文章是对之前的文章 “使用 Llama 3 开源和 Elastic 构建 RAG” 的一个补充。我们可以在本地部署 Elasticsearch&#xff0c;并进行展示。我们将一步一步地来进行配置并展示。你还可以参考我之前的另外一篇文章 “Elasticsearch&#xff1a;使用在本地计算机上运行的 LLM 以…...

AcWing算法基础课笔记——高斯消元

高斯消元 用来求解方程组 a 11 x 1 a 12 x 2 ⋯ a 1 n x n b 1 a 21 x 1 a 22 x 2 ⋯ a 2 n x n b 2 … a n 1 x 1 a n 2 x 2 ⋯ a n n x n b n a_{11} x_1 a_{12} x_2 \dots a_{1n} x_n b_1\\ a_{21} x_1 a_{22} x_2 \dots a_{2n} x_n b_2\\ \dots \\ a…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...