当前位置: 首页 > 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…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...