HOW - 基于组件库组件改造成自定义组件基本规范

news2025/5/24 18:09:43

文章目录

  • Select 选择器改造
    • 1. 明确组件目标
    • 2. 定义组件 API
    • 3. 合理使用默认值
    • 4. 支持类型安全的 options 传递
    • 5. 支持 ForwardRef(可选)
    • 6. 封装样式(可选)
    • 7. 使用示例
  • ...props 位置
    • 推荐顺序:最后
    • 原因:
    • 简要总结
  • 合并内外部逻辑
    • 场景示例:处理 onChange
    • 方案一:手动合并函数或属性
    • 方案二:兼顾默认值 + 用户自定义
    • 总结:封装时处理逻辑建议
    • 最佳实践示例组件
  • 更安全的方式

Select 选择器改造

比如,要将 Ant Design 的 Select 组件封装成你的 CustomSelect 组件并规范化封装,建议遵循以下几个方面的最佳实践:

1. 明确组件目标

你可以定义这个 CustomSelect 的目标,例如:

  • 更统一的样式
  • 集成默认功能(比如加载状态、本地搜索等)
  • 简化使用(比如默认占位符、默认事件处理)

2. 定义组件 API

设计你自己的 CustomSelect 组件的 props 类型时,建议基于 antd 的 SelectProps 做扩展:

// CustomSelect.tsx
import React from 'react';
import { Select, SelectProps } from 'antd';

export interface CustomSelectProps extends SelectProps {
  label?: string; // 可选,封装 label
  wrapperClassName?: string; // 可选,外层 class
}

const CustomSelect: React.FC<CustomSelectProps> = ({
  label,
  wrapperClassName,
  ...props
}) => {
  return (
    <div className={wrapperClassName}>
      {label && <label className="block mb-1 text-gray-700">{label}</label>}
      <Select {...props} />
    </div>
  );
};

export default CustomSelect;

3. 合理使用默认值

在封装中添加默认值可以提升使用体验:

<Select
  showSearch
  allowClear
  placeholder="请选择"
  optionFilterProp="label"
  filterOption={(input, option) =>
    (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
  }
  {...props}
/>

你可以在 CustomSelect 内设置 showSearchallowClearfilterOption 等默认行为。

4. 支持类型安全的 options 传递

你可以加一个 options 支持(类型为 DefaultOptionType[]):

import type { DefaultOptionType } from 'antd/es/select';

interface CustomSelectProps extends SelectProps {
  options?: DefaultOptionType[];
}

并配合传入:

<Select
  options={props.options}
  {...otherProps}
/>

5. 支持 ForwardRef(可选)

如果你希望外部能访问内部 ref,可以使用 forwardRef

const CustomSelect = React.forwardRef<any, CustomSelectProps>((props, ref) => {
  return <Select ref={ref} {...props} />;
});

6. 封装样式(可选)

统一样式可以放在 CustomSelect.module.css 或用 tailwind 写死样式:

<Select className="w-full rounded-md" />

7. 使用示例

<CustomSelect
  label="城市"
  value={selectedCity}
  onChange={setSelectedCity}
  options={[
    { label: '北京', value: 'beijing' },
    { label: '上海', value: 'shanghai' }
  ]}
/>

…props 位置

{...props} 应该放在 最后面

推荐顺序:最后

<Select
  showSearch
  allowClear
  placeholder="请选择"
  {...props}
/>

原因:

  1. 避免被覆盖
    如果你把 ...props 放在前面,后面设置的属性会覆盖它,导致用户传入的属性失效。

    // 错误示例(可能导致用户传入的属性无效)
    <Select
      {...props}
      showSearch={false}  // 会覆盖 props.showSearch,即使用户传了 true
    />
    
  2. 正确示例:用户可以覆盖默认行为

    <Select
      showSearch
      allowClear
      placeholder="请选择"
      {...props}  // 用户传入的值会覆盖上面的默认值
    />
    

    例如用户传入 allowClear={false},最终就会生效。

简要总结

放置位置是否推荐原因说明
最后面✅ 推荐用户传入值可覆盖默认值
最前面❌ 不推荐默认值会覆盖用户传入值,造成困惑

如果你还封装了内部逻辑(比如 onChange 的包裹处理),那可以手动合并它,而不是直接写在默认值中。

合并内外部逻辑

如果你希望在自定义组件中:

内部自定义属性可以“加工”后使用
同时仍 兼容外部传进来的属性,即可以被用户覆写/增强

场景示例:处理 onChange

我们以 onChange 为例,如果你想在组件内部处理一些逻辑后再执行用户传入的 onChange,做法如下:

方案一:手动合并函数或属性

const handleChange = (value: any, option: any) => {
  // 自定义逻辑,比如打日志
  console.log('[CustomSelect] selected:', value);

  // 调用外部传入的 onChange(如果有)
  props.onChange?.(value, option);
};

<Select
  showSearch
  allowClear
  placeholder="请选择"
  {...props}
  onnChange={handleChange}
/>

方案二:兼顾默认值 + 用户自定义

例如:

<Select
  showSearch={props.showSearch ?? true} // 外部可以传 false,否则默认 true
  allowClear={props.allowClear ?? true}
  placeholder={props.placeholder ?? '请选择'}
  {...props}
/>

这样可以兼顾默认值 + 用户自定义。

总结:封装时处理逻辑建议

类型写法是否允许外部覆盖
函数型属性主动调用外部函数(如 onChange)✅ 推荐
布尔/字符串属性使用 ?? 提供默认值✅ 推荐

最佳实践示例组件

export const CustomSelect: React.FC<CustomSelectProps> = ({
  label,
  wrapperClassName,
  onChange,
  ...props
}) => {
  const handleChange = (value: any, option: any) => {
    // 内部逻辑
    console.log('[CustomSelect] selected:', value);

    // 外部逻辑
    onChange?.(value, option);
  };

  return (
    <div className={wrapperClassName}>
      {label && <label className="block mb-1 text-gray-700">{label}</label>}
      <Select
        showSearch={props.showSearch ?? true}
        allowClear={props.allowClear ?? true}
        placeholder={props.placeholder ?? '请选择'}
        {...props}
        onChange={handleChange}
      />
    </div>
  );
};

更安全的方式

更安全的方式是明确列出你需要的 props,而不是使用 {...props}

  const handleChange = (value: any, option: any) => {
    // 内部逻辑
    console.log('[CustomSelect] selected:', value);

    // 外部逻辑
    onChange?.(value, option);
  };
  
<Select
  showSearch
  allowClear
  placeholder="请选择"
  onChange={handleChange}
  // 明确列出其他需要的 props
  style={props.style}
  className={props.className}
  // 其他需要的 props...
/>

即建议不要偷懒,直接使用 ...props,而是使用什么传入什么。并且可以参考 onChagne 一样合并内外部逻辑。

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

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

相关文章

九州未来十三载:开源赋能 智启未来

2012年&#xff0c;九州未来以“开源赋能云边变革”为使命&#xff0c;开启中国开放云边基础架构服务的探索之路。十三载坚守深耕&#xff0c;我们始终以开源为翼&#xff0c;以算力为基&#xff0c;在科技浪潮中砥砺前行&#xff0c;见证并推动着AI时代的算力变革。 坚守初心丨…

2025年AI搜索引擎发展洞察:技术革新与市场变革

引言&#xff1a;AI搜索的崛起与市场格局重塑 2024-2025年&#xff0c;AI搜索市场迎来了前所未有的变革期。随着DeepSeek-R1等先进大语言模型的推出&#xff0c;传统搜索引擎、AI原生搜索平台以及各类内容平台纷纷加速智能化转型&#xff0c;推动搜索技术从基础信息检索向深度…

dify调用Streamable HTTP MCP应用

一、概述 上一篇文章&#xff0c;介绍了使用python开发Streamable HTTP MCP应用&#xff0c;链接&#xff1a;https://www.cnblogs.com/xiao987334176/p/18872195 接下来介绍dify如何调用MCP 二、插件 安装插件 需要安装2个插件&#xff0c;分别是&#xff1a;Agent 策略(支持 …

HCIP实验五

一、实验拓扑图&#xff1a; 二、实验需求分析&#xff1a; 1. PreVal策略&#xff1a;要求确保R4通过R2到达192.168.10.0/24 &#xff0c;需在R4上针对去往该网段路由配置PreVal策略&#xff0c;为经R2的路径赋予更高优先值&#xff0c;影响本地路由表选路。 2. AS Path策略…

vivado fpga程序固化

一般下载到fpga上的程序在掉电之后就会丢失&#xff0c;如果想要掉电之后程序不丢失&#xff0c;就需要将比特流文件固化到板载的flash上。 以下以我的7a100t开发板为例&#xff0c;介绍程序固化的流程 点击OK就可以下载了。 一个奇怪的问题 有一次我的一个工程固化之后&…

OpenCV CUDA模块图像特征检测与描述------图像中快速检测特征点类cv::cuda::FastFeatureDetector

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::FastFeatureDetector 是 OpenCV 的 CUDA 加速模块中的一部分&#xff0c;用于在图像中快速检测特征点。FAST&#xff08;Features fro…

SpringMVC(结合源码浅析工作流程)

SpringMVC 概念 Spring MVC 是基于前端控制器&#xff08;Front Controller&#xff09;设计模式的 Web 框架&#xff0c;在 Web 应用中指一个统一的入口&#xff0c;用来接收所有客户端请求&#xff0c;并统一进行分发、处理。在 SpringMVC 中&#xff0c;前端控制器就是 Di…

学习STC51单片机13(芯片为STC89C52RC)

我去&#xff0c;兄弟们我们今天来学习一个牛逼 的硬件&#xff0c;它叫超声波测距模块HC—SR04 硬件&#xff1a;HC—SR04 哎&#xff0c;想当初最想要玩的就是这个模块&#xff0c;科技感十足&#xff0c;那现在就让我们玩玩吧 超声波测距传感器 原理就是说需要给Trig 10u…

Claude 4 系列 Opus 4 与 Sonnet 4正式发布:Claude 4新特性都有哪些?

随着 Claude 4 系列&#xff08;Opus 4 与 Sonnet 4&#xff09;的正式发布&#xff0c;Anthropic 把自家大模型从“会聊天”推进到“能当自主代理”──不仅推理更深、上下文更长&#xff0c;还内置代码执行、多模态理解、工具调用等一揽子全新能力&#xff1b;同时&#xff0…

深度“求索”:DeepSeek+Dify构建个人知识库

目录 前言 环境部署 安装Docker 安装Dify 配置Dify 部署知识库 创建应用 前言 在当今数字化信息爆炸的时代&#xff0c;数据隐私和个性化知识管理成为企业和个人关注的焦点。Dify&#xff0c;作为一款备受瞩目的开源 AI 应用开发平台&#xff0c;为用户提供了完整的私有…

基于R语言的空间异质性数据分析技术

在自然和社会科学领域&#xff0c;存在大量与地理或空间相关的数据&#xff0c;这些数据通常具有显著的空间异质性。传统的统计学方法在处理这类数据时往往力不从心。基于R语言的一系列空间异质性数据分析方法&#xff0c;如地理加权回归&#xff08;GWR&#xff09;、地理加权…

网络学习-TCP协议(七)

一、TCP协议 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。 1、三次握手 客户端&#xff1a; 1、先发起连接&#xff0c;发送SYN置1&#xff0c;seqnum12345(随机值)----半连接…

基于微信小程序的高校校园微活动管理系统设计与实现(源码+定制+开发)高校微信小程序校园活动发布与互动平台开发 面向大学生群体的校园活动移动平台设计与实现

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

云计算与大数据进阶 | 27、存储系统如何突破容量天花板?可扩展架构的核心技术与实践—— 分布式、弹性扩展、高可用的底层逻辑(上)

数据中心里&#xff0c;存储系统是至关重要的组成部分。由于相关硬件组件与存储操作系统的多样性和复杂性&#xff0c;如何在保证存储稳定、安全、可靠的同时&#xff0c;实现灵活扩展和自服务&#xff0c;一直是困扰数据中心全面云化的难题。 简单来说&#xff0c;现在的难题…

IvorySQL-WASM:免安装的数据库探索之旅

简介 为了降低社区用户的使用门槛&#xff0c;提升使用体验&#xff0c;IvorySQL 社区特别推出了 IvorySQL-WASM 项目&#xff0c;帮助用户快速在线 Demo。 IvorySQL-WASM 基于开源的 Postgres-WASM 框架开发。它允许用户直接在网页浏览器中体验 IvorySQL&#xff0c;无需本地…

飞牛fnNAS远程映射盘符

目录 一、NAS、PC端配置Zerotier 二、使用网上邻居 三、使用WebDAV 1.开启WebDAV 2.PC上安装RaiDrive并设置 如果能将NAS作为本机一个盘符来使用,一定会令我非常方便。如果是本地,可以很方便实现。 将飞牛NAS映射为本地盘符,常用两种方式,一种是网上邻居,另一种是We…

Java设计模式:探索编程背后的哲学

设计模式是软件开发中的一种常见方法&#xff0c;它为常见问题提供了解决方案。在Java世界中&#xff0c;设计模式的应用尤为广泛。本文将深入探讨Java设计模式的起源、分类和实际应用&#xff0c;帮助读者更好地理解和应用这些模式。设计模式不仅是编程的技术&#xff0c;更是…

Docker部署OpenSearch集群

OpenSearch 简介 OpenSearch 是一款开源的搜索与分析引擎&#xff0c;最初由亚马逊 AWS 开发&#xff0c;于 2021 年 9 月将其移交至 Linux 基金会旗下的 OpenSearch 软件基金会&#xff0c;此后实现了社区主导的治理模式。其具有高性能、可扩展性强、兼容性强等优点&#xff…

【AS32X601驱动系列教程】PLIC_中断应用详解

平台中断控制器&#xff08;Platform Level Interrupt Controller&#xff0c;PLIC&#xff09;是国科安芯AS32系列MCU芯片的中断控制器&#xff0c;主要对中断源进行采样&#xff0c;优先级仲裁和分发。各外设中断统一连到PLIC&#xff0c;PLIC统一管理并输出中断请求到内核。…

python学习打卡day34

DAY 34 GPU训练及类的call方法 知识点回归&#xff1a; CPU性能的查看&#xff1a;看架构代际、核心数、线程数GPU性能的查看&#xff1a;看显存、看级别、看架构代际GPU训练的方法&#xff1a;数据和模型移动到GPU device上类的call方法&#xff1a;为什么定义前向传播时可以直…