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输入框组件,并提供一些常用的功能,你可以选择不同的 尺寸、添加前缀、显示加载状态、触发回调函数、自定义样式 等等。这些功能在这个项目中…...
php composer 报错
引用文章: 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 …...
数据安全如何防护?迅软加密软件保护企业数据资产
前言:加密软件是一种重要的工具,可以帮助企业保护其数据资产的安全。通过使用加密算法,加密软件可以将敏感数据转化为无法理解的密文,只有授权的用户才能解密并访问这些数据。 一、迅软加密软件保护企业数据资产的关键方面 1、数…...
Android 11 ,默认授予预置应用/APK 需要的权限,解决permission denied for window type 2003 问题。
写这篇文章的原因是解决了一个APP闪退的问题,闪退的原因是插拔U盘时,注册的广播接收者接收到广播需要弹出一个Dialog询问是否需要打开U盘,这个Dialog设置的是系统级别悬浮窗,没有这个权限,报错导致闪退,下面…...
RabbitMQ(消息队列)
RabbitMQ 它是消息中间件,是在消息的传输过程中保存消息的容器,实现应用程序和应用程序之间通信的中间产品。目前主流消息队列通讯协议是AMQP(二进制传输,支持多种语言)、JMS(HTTP传输,只支持J…...
LeetCode-数组/回溯-No40组合总和II
题目: 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次 。 注意:解集不能包含重复的组合。 示例 1: 输入: ca…...
直接调用 Java 线程的 run() 方法会发生什么?
文章目录 前言回顾run() 方法 vs start() 方法run()方法start()方法 直接调用 run() 方法的影响直接调用 run() 方法调用 start() 方法 示例解析结论个人简介 前言 在Java中,多线程编程是一个重要的概念,尤其是在处理并发任务时。线程是Java中实现多线程…...
计算机毕业设计Thinkphp/Laravel学生考勤管理系统zyoqy
管理员登录学生考勤管理系统后,可以对首页、个人中心、公告信息管理、年级管理、专业管理、班级管理、学生管理、教师管理、课程信息管理、学生选课管理、课程签到管理、请假申请管理、销假申请管理等功能进行相应操作,如图5-2所示。学生登录进入学生考勤…...
3浏览器安全
上一篇👉: 浏览器渲染原理 浏览器安全涉及多方面的威胁与防护,其中XSS(跨站脚本攻击)与CSRF(跨站请求伪造)是最常见的两类安全问题,而中间人攻击与网络劫持也是不容忽视的安全隐患。下面是对这…...
昇思25天学习打卡Day01
实验结果 心得体会 趁着假期,跟谁官方实战营开始系统学习MindSpore深度学习框架。昇思MindSpore是一个全场景深度学习框架,旨在实现易开发、高效执行、全场景统一部署三大目标。其中易开发表现为API友好,调试难度低;高效执行包括…...
Python-爬虫 下载天涯论坛帖子
为了爬取的高效性,实现的过程中我利用了python的threading模块,下面是threads.py模块,定义了下载解析页面的线程,下载图片的线程以及线程池 import threading import urllib2 import Queue import re thread_lock threading.RL…...
创建github个人博客
文章目录 安装Hexo安装git安装Node.js安装 Hexo git配置SSH key配置ssh 搭建个人博客新建博客生成静态网页 本文主要参考 【保姆级】利用Github搭建自己的个人博客,看完就会 安装Hexo 参考官方文档:https://hexo.io/zh-cn/docs/ Hexo 是一个快速、简洁且…...
【五子棋game】
编写一个五子棋游戏程序可以分为几个步骤:设计棋盘、定义规则、实现人机交互、判断胜负。下面是一个简化的五子棋游戏程序示例,使用Python语言编写。 首先,我们需要一个棋盘。可以使用一个二维数组来表示棋盘,其中0表示空位&#…...
从入门到精通:使用Python的Watchdog库监控文件系统的全面指南
从入门到精通:使用Python的Watchdog库监控文件系统的全面指南 引言Watchdog库概述核心组件工作原理 快速开始:设置Watchdog安装Watchdog创建一个简单的监控脚本设置和启动Observer 事件处理:如何响应文件系统的变化基本事件处理处理复杂的场景…...
Linux 进程管理指令
Linux 进程管理是系统管理的重要部分,通过各种工具和命令,你可以查看、控制、调试和管理进程。以下是一些常用的 Linux 进程管理命令和工具。 查看进程 1. ps ps 命令用于列出当前系统的进程。 查看当前用户的所有进程: ps -u $USER查看…...
Java OA系统通知公告模块
### 使用Spring Boot实现OA通知公告模块 使用Spring Boot框架实现一个支持多种形式公告发布、设置发布时间和有效期,以及公告发布后推送通知的模块。 #### 项目结构 结构组织项目: OA_Notification_Module/ ├── src/ │ ├── main/ │ │ …...
简约的服务器监控工具Ward
什么是 Ward ? Ward 是一个简单简约的服务器监控工具。 Ward 支持自适应设计系统。此外,它还支持深色主题。它仅显示主要信息,如果您想查看漂亮的仪表板而不是查看一堆数字和图表,则可以使用它。 Ward 在所有流行的操作系统上都能…...
新能源发电乙级资质所需办理标准
企业资历与信誉: 必须具有独立企业法人资格。社会信誉良好,注册资本不少于100万元人民币。 技术条件: 专业技术人员配置齐全、合理,数量需满足资质标准要求。主要技术负责人或总工程师应具有大学本科以上学历、10年以上设计经历&a…...
Elasticsearch:使用 Llamaindex 的 RAG 与 Elastic 和 Llama3
这篇文章是对之前的文章 “使用 Llama 3 开源和 Elastic 构建 RAG” 的一个补充。我们可以在本地部署 Elasticsearch,并进行展示。我们将一步一步地来进行配置并展示。你还可以参考我之前的另外一篇文章 “Elasticsearch:使用在本地计算机上运行的 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…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...
qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...
【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法
使用 ROS1-Noetic 和 mavros v1.20.1, 携带经纬度海拔的话题主要有三个: /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码,来分析他们的发布过程。发现前两个话题都对应了同一…...
Vue 实例的数据对象详解
Vue 实例的数据对象详解 在 Vue 中,数据对象是响应式系统的核心,也是组件状态的载体。理解数据对象的原理和使用方式是成为 Vue 专家的关键一步。我将从多个维度深入剖析 Vue 实例的数据对象。 一、数据对象的定义方式 1. Options API 中的定义 在 Options API 中,使用 …...
