前言

上篇我们讲了Icon组件,Icon组件是Antd源码库中实现比较简单的组件,适合大家入门,这篇文章主要和大家一起分析一下数字输入框组件,即InputNumber,难度适中,但蕴含的Antd里较为经典的开发场景,适合大家比较深入的了解Antd背后的思想。

这篇我们学习的目的主要有:

  • 学习Antd的如何基于现有的组件封装
  • 封装背后的技术目的和效果如何

目录结构

首先我们依旧看看位于components 文件夹下的input-number 目录结构:

InputNumber组件的的效果图如下:

代码

InputNumber的核心代码位于 index.tsx 内,代码不多,我们直接贴过来:

import * as React from 'react';
import classNames from 'classnames';
import RcInputNumber from 'rc-input-number';export interface InputNumberProps {prefixCls?: string;min?: number;max?: number;value?: number;step?: number | string;defaultValue?: number;tabIndex?: number;onKeyDown?: React.FormEventHandler<any>;onChange?: (value: number | string | undefined) => void;disabled?: boolean;size?: 'large' | 'small' | 'default';formatter?: (value: number | string | undefined) => string;parser?: (displayValue: string | undefined) => number;placeholder?: string;style?: React.CSSProperties;className?: string;name?: string;id?: string;precision?: number;
}export default class InputNumber extends React.Component<InputNumberProps, any> {static defaultProps = {prefixCls: 'ant-input-number',step: 1,};private inputNumberRef: any;render() {const { className, size, ...others } = this.props;const inputNumberClass = classNames({[`${this.props.prefixCls}-lg`]: size === 'large',[`${this.props.prefixCls}-sm`]: size === 'small',}, className);return <RcInputNumber ref={(c: any) => this.inputNumberRef = c} className={inputNumberClass} {...others} />;}focus() {this.inputNumberRef.focus();}blur() {this.inputNumberRef.blur();}
}

主要结构非常清晰,分成三个部分,头部的文件引入,参数校验,主体类声明。

文件的引入中,react大家非常熟悉,classnames 在上篇文章,河马君为大家介绍过使用方法和实现,对于rc-input-number可能部分读者比较陌生,我们来介绍一下。

Antd的许多组件都是基于rc-xxx组件分装,比如常见的Table组件是基于rc-table,Form组件基于rc-form,rc-xxx来源于react-component组件库,里面有很多常用的组件,大家也可以在项目中直接使用,也可以经过自己二次封装后使用。我们稍后仔细分析一下rc-input-number,先来看看参数校验和主体结构。

参数校验

对于参数校验,当然需要对照InputNumber的文档看了,官方的使用说明如下:

属性如下:

成员 说明 类型 默认值
autoFocus 自动获取焦点 boolean false
defaultValue 初始值 number
disabled 禁用 boolean false
formatter 指定输入框展示值的格式 function(value: number \ string): string
max 最大值 number Infinity
min 最小值 number -Infinity
parser 指定从 formatter 里转换回数字的方式,和 formatter 搭配使用 function( string): number -
precision 数值精度 number -
size 输入框大小 string
step 每次改变步数,可以为小数 number\ string
value 当前值 number
onChange 变化回调 Function(value: number \ string)

那我们再来对照代码里的参数校验,文档中有的就不再赘述,缺少的通过注释给出:

export interface InputNumberProps {prefixCls?: string;   // Antd预留给自己的预设class,这里在defaultProps中默认设置为'ant-input-number'min?: number;max?: number;value?: number;step?: number | string;defaultValue?: number;tabIndex?: number;    //tab 键控制次序,就是快捷切换onKeyDown?: React.FormEventHandler<any>;  // 用户按下键盘按键时的回调函数onChange?: (value: number | string | undefined) => void;disabled?: boolean;size?: 'large' | 'small' | 'default';formatter?: (value: number | string | undefined) => string;parser?: (displayValue: string | undefined) => number;placeholder?: string;     // placeholder提示style?: React.CSSProperties;  // 用户自定义styleclassName?: string;   // 用户自定义classname?: string;    // 用户自定义name属性,毕竟底层是input标签id?: string;  // 用户自定义idprecision?: number;
}

对于其中TypeScript形式类型校验,可以参考上篇文章,这里Antd文档给出了其自定义的参数列表,省略了默认的普通参数,所以通过对于源码的学习,能够清晰的知道在官方文档之外,哪些参数是可用的。

主体函数

export default class InputNumber extends React.Component<InputNumberProps, any> {// 默认参数设置static defaultProps = {prefixCls: 'ant-input-number',step: 1,};// 通过ref属性获取实例private inputNumberRef: any;render() {const { className, size, ...others } = this.props;// className的判断和合成const inputNumberClass = classNames({[`${this.props.prefixCls}-lg`]: size === 'large',[`${this.props.prefixCls}-sm`]: size === 'small',}, className);// 核心RcInputNumber组件,我们稍后讲解一下return <RcInputNumber ref={(c: any) => this.inputNumberRef = c} className={inputNumberClass} {...others} />;}// 通过实例绑定的focus事件和blur事件focus() {this.inputNumberRef.focus();}blur() {this.inputNumberRef.blur();}
}

这是官方给出的方法文档:

名称 描述
blur() 移除焦点
focus() 获取焦点

这里河马君多说一下,对于这两个函数的实现,Antd使用了ref属性,实现对组件的引用

ref={(c: any) => this.inputNumberRef = c}

这是通过ref回调的方式,在组件render完获取实例,优于React提供的旧版的this.refs.inputNumberRef字符串形式,但在最新版React16.2的文档中,官方建议使用React.createRef(),这里用普通的写法可以写为:

  constructor(props) {super(props);this.inputNumberRef = React.createRef();}...render() {...return <RcInputNumber ref={this.inputNumberRef} className={inputNumberClass} {...others} />;}focus() {this.inputNumberRef.focus();}blur() {this.inputNumberRef.blur();}
}

到这里,对于InputNumber组件的源码主体结构介绍完了,我们下一篇文章,分析一下核心的rc-input-number源码,即<RcInputNumber/>组件的实现。

Antd源码浅析(二)InputNumber组件 一相关推荐

  1. LinkedList类源码浅析(二)

    1.上一节介绍了LinkedList的几个基本的方法,其他方法类似,就不一一介绍: 现在再来看一个删除的方法:remove(Object o) remove方法接受一个Object参数,这里需要对参数 ...

  2. Android应用Preference相关及源码浅析(Preference组件家族篇)

    | public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) | @ ...

  3. tio-http-server 源码浅析(二)Http请求的处理HttpRequestHandler

    前言 在上一篇<tio-http-server 源码浅析(一)HttpRequestDecoder的实现>简单分析了HttpRequestDecoder的源码,并且已经得到了HttpReq ...

  4. 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 JobMasger启动 YarnJobClusterEntrypoint

    1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [三] 上一章:[flink]Flink 1.12.2 源码浅析 : yarn-per-job模式解析 yar ...

  5. antd源码-spin解析

    antd源码-spin解析 spin的作用是代表当前块正在加载中 Spin 元素的渲染 renderSpin = ({ getPrefixCls }: ConfigConsumerProps) =&g ...

  6. 深入探索Android 启动优化(七) - JetPack App Startup 使用及源码浅析

    本文首发我的微信公众号:徐公,想成为一名优秀的 Android 开发者,需要一份完备的 知识体系,在这里,让我们一起成长,变得更好~. 前言 前一阵子,写了几篇 Android 启动优化的文章,主要是 ...

  7. 【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  8. Android Loader机制全面详解及源码浅析

    原文出处:csdn@工匠若水,http://blog.csdn.net/yanbober/article/details/48861457 一.概述 在Android中任何耗时的操作都不能放在UI主线 ...

  9. asp.net core源码飘香:Logging组件

    简介: 作为基础组件,日志组件被其他组件和中间件所使用,它提供了一个统一的编程模型,即不需要知道日志最终记录到哪里去,只需要调用它即可. 使用方法很简单,通过依赖注入ILogFactory(Creat ...

最新文章

  1. 【Codeforces】158B-Taxi(贪心,怎么贪咧)
  2. android 字符串相似度对比,Android中的OpenCV图像比较和相似度
  3. Sklearn参数详解—LR模型
  4. 如何备份linux系统(转)
  5. mysql anyvalue函数_Mysql 的ANY_VALUE()函数和 ONLY_FULL_GROUP_BY 模式
  6. python变量使用前必须先声明、并且一旦声明_初学者学习Python的30天‍-第18天-文件处理...
  7. Java StringBuilder length()方法与示例
  8. 腾讯和阿里巴巴考虑互相开放生态,是真开放还是新的垄断?
  9. 7-96 福到了 (15 分)
  10. java 静态方法 变量_Java变量的初始化及静态方法的实现
  11. P1828 香甜的黄油 (spfa)
  12. cad转dwf简易教程
  13. Js解决微信浏览器刷新的问题
  14. case when 嵌套
  15. day11 反转字符串||反转字符串2
  16. 喝了38年的雪碧变样了!中国首发上市,白标原味、黑标无糖,加入两款新品 | 美通社头条...
  17. Oracle 18c ORA-01035: ORACLE only available to users with RESTRICTED SESSION privilege
  18. 什么是离散事件模拟(DES)
  19. 建行u盾弹不出来_关于建设银行网银的问题```
  20. 还叫 “不可成药” 靶点?KRAS 已逆袭!- MedChemExpress

热门文章

  1. 2022电商行业重磅年度报告:八大年度关键词盘点
  2. 电视台的流媒体地址 mms
  3. 中国式众筹:促销,众筹?(转)
  4. 基于顺序表的图书管理系统(C语言)
  5. Javascript的IE和Firefox兼容性
  6. Kafka 的七年之痒
  7. python汽车数据分析_用python对汽车油耗进行数据分析
  8. LeetCode 1374.生成每种字符都是奇数个的字符串
  9. 在安卓的道路上铿锵前行
  10. Linux 第三章 压缩与归档 文件搜索、排序