antd原始碼解析(二)button控制元件的解析
第一節我們看了antd的button原始碼,現在我們用class的常用寫法改造下:
import React,{ Component } from "React";
var _classnames2 = require('classnames');
var rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
var isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
function isString(str) {
return typeof str === 'string';
}
var __rest = undefined && undefined.__rest || function (s, e) {
var t = {};
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
}
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]];
}
return t;
};
class Button extends Component {
//初始化state
state = {
loading: this.props.loading
}
//建構函式
constructor(props) {
super(props);
[
'handleClick', 'handleMouseUp'
].forEach(func=> {
this[func] = this[func].bind(this );
});
}
//props的值發生變更時呼叫的方法
componentWillReceiveProps(nextProps) {
var _this2 = this;
var currentLoading = this.props.loading;
var loading = nextProps.loading;
if (currentLoading) {
clearTimeout(this.delayTimeout);
}
if (typeof loading !== 'boolean' && loading && loading.delay) {
this.delayTimeout = setTimeout(function () {
return _this2.setState({loading: loading});
}, loading.delay);
} else {
this.setState({loading: loading});
}
}
componentWillUnmount() {
if (this.timeout) {
clearTimeout(this.timeout);
}
if (this.delayTimeout) {
clearTimeout(this.delayTimeout);
}
}
handleClick(e){
// Add click effect
this.setState({clicked: true});
clearTimeout(this.timeout);
var _this=this;
this.timeout = setTimeout(function () {
return _this.setState({clicked: false});
}, 500);
var onClick = this.props.onClick;
if (onClick) {
onClick(e);
}
}
handleMouseUp(e){
if (this.props.onMouseUp) {
this.props.onMouseUp(e);
}
}
render() {
var _classNames;
//從props和state裡獲取相應的屬性。
var _a = this.props,
type = _a.type,
shape = _a.shape,
_a$size = _a.size,
size = _a$size === undefined ? '' : _a$size,
className = _a.className,
htmlType = _a.htmlType,
children = _a.children,
icon = _a.icon,
prefixCls = _a.prefixCls,
ghost = _a.ghost,
others = __rest(_a, ["type", "shape", "size", "className", "htmlType", "children", "icon", "prefixCls", "ghost"]);
var _state = this.state,
loading = _state.loading,
clicked = _state.clicked;
// large => lg
// small => sm
var sizeCls = '';
switch (size) {
case 'large':
sizeCls = 'lg';
break;
case 'small':
sizeCls = 'sm';
default:
break;
}
function insertSpace(child, needInserted) {
// Check the child if is undefined or null.
if (child == null) {
return;
}
var SPACE = needInserted ? ' ' : '';
// strictNullChecks oops.
if (typeof child !== 'string' && typeof child !== 'number' && isString(child.type) && isTwoCNChar(child.props.children)) {
return React.cloneElement(child, {}, child.props.children.split('').join(SPACE));
}
if (typeof child === 'string') {
if (isTwoCNChar(child)) {
child = child.split('').join(SPACE);
}
return React.createElement(
'span',
null,
child
);
}
return child;
}
//定義_classNames 的相關屬性
var iconType = 'loading';
var children = this.props.children;
var needInserted = React.Children.count(children) === 1 && !iconType;
var kids = React.Children.map(children, function (child) {
return insertSpace(child, needInserted);
});
var _classNames = {}
_classNames[prefixCls + '-' + type]=type;
_classNames[prefixCls + '-' + shape]=shape;
_classNames[prefixCls + '-' + sizeCls]=sizeCls;
_classNames[prefixCls + '-icon-only']= !children && icon && !loading;
_classNames[prefixCls + '-loading']=loading;
_classNames[prefixCls + '-clicked']=clicked;
_classNames[prefixCls + '-background-ghost']=ghost;
var classes = _classnames2(prefixCls, className,_classNames);
//建立相應的元素
return React.createElement(
'button',
{
type: htmlType || 'button',
className: classes,
onMouseUp: this.handleMouseUp,
onClick: this.handleClick
},
kids
);
}
}
//設定props的預設值
Button.defaultProps = {
prefixCls: 'ant-btn',
loading: false,
clicked: false,
ghost: false
};
//屬性型別校驗
Button.propTypes = {
type: React.PropTypes.string,
shape: React.PropTypes.oneOf(['circle', 'circle-outline']),
size: React.PropTypes.oneOf(['large', 'default', 'small']),
htmlType: React.PropTypes.oneOf(['submit', 'button', 'reset']),
onClick: React.PropTypes.func,
loading: React.PropTypes.oneOfType([React.PropTypes.bool, React.PropTypes.object]),
className: React.PropTypes.string,
icon: React.PropTypes.string
};
Button.__ANT_BUTTON = true;
export default Button;
其實就是把裡面費勁的程式碼改成相應的常用程式碼而已,就基本能看懂了。
var Button = function (_React$Component) {
(0, _inherits3['default'])(Button, _React$Component);
其實為了實現繼承React.Component
class Button extends Component {
看著這段程式碼,其實就是想給json設定值而已:
(0, _defineProperty3['default'])(_classNames, prefixCls + '-' + type, type),
(0, _defineProperty3['default'])(_classNames, prefixCls + '-' + shape, shape),
(0, _defineProperty3['default'])(_classNames, prefixCls + '-' + sizeCls, sizeCls),
(0, _defineProperty3['default'])(_classNames, prefixCls + '-icon-only', !children && icon && !loading),
(0, _defineProperty3['default'])(_classNames, prefixCls + '-loading', loading),
(0, _defineProperty3['default'])(_classNames, prefixCls + '-clicked', clicked),
(0, _defineProperty3['default'])(_classNames, prefixCls + '-background-ghost', ghost),
_classNames[prefixCls + '-' + type]=type;
_classNames[prefixCls + '-' + shape]=shape;
_classNames[prefixCls + '-' + sizeCls]=sizeCls;
_classNames[prefixCls + '-icon-only']= !children && icon && !loading;
_classNames[prefixCls + '-loading']=loading;
_classNames[prefixCls + '-clicked']=clicked;
_classNames[prefixCls + '-background-ghost']=ghost;
state預設值設定:
_this.state = {
loading: props.loading
};
也就對應了下面程式碼
state = {
loading: this.props.loading
}
還有就是
(0, _createClass3['default'])(Button, [
{
key: 'componentWillReceiveProps',
....
這個就不用解釋了,其實就是定義了相應的函式而已。
相關推薦
antd原始碼解析(二)button控制元件的解析
第一節我們看了antd的button原始碼,現在我們用class的常用寫法改造下: import React,{ Component } from "React"; var _classnames2 = require('classnames');
antd原始碼解析(一)button控制元件的解析
先看下antd的button的原始碼。 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('bab
spring原始碼剖析(二)Spring預設標籤解析及註冊實現
在使用spring的時候,我也經常會使用到bean標籤,beans標籤,import標籤,aop標籤等。 下面主要為讀者介紹spring的預設的自帶標籤的解析流程。 驗證模式(DTD&XSD) dtd基本已被淘汰,現在spring的驗證模式基本都是採用xsd檔案
winform控制元件縮寫(二)容器控制元件
winform控制元件縮寫(二)容器控制元件 序號 縮寫 空間名 1 flp FlowLayoutPanel 2 grp
elementui 後臺管理系統遇到的問題(二) 樹形控制元件 el-tree
elementui中樹形控制元件的使用 一、將後臺返回的資料填充到前端控制元件中,需要注意的幾點問題 (1)、el-tree中需要繫結node-key='自定義的id名稱' (2)、在配置data中defaultProps中的屬性時,要按照與後端協商的欄位名稱對稱 (3)、重要的是要月後端協商返回欄位內容
Android 5.0+ 解析(五)FloatingActionButton控制元件
今天給大家帶來一個效果比較好的而且很容易實現的控制元件FloatingActionButton!我們一起來對FloatingActionButton做一些基本瞭解吧! FloatingActionButton簡單介紹 FloatingActionButton是繼承至Imag
Spring原始碼解析(二)——元件註冊2
import com.ken.service.BookService; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.
zigbee 之ZStack-2.5.1a原始碼分析(二) 無線接收控制LED
本文描述ZStack-2.5.1a 模板及無線接收移植相關內容。 main HAL_BOARD_INIT // HAL_TURN_OFF_LED1 InitBoard HalDriverInit HalAdcInit
認真的 Netty 原始碼解析(二)
Channel 的 register 操作 經過前面的鋪墊,我們已經具備一定的基礎了,我們開始來把前面學到的內容揉在一起。這節,我們會介紹 register 操作,這一步其實是非常關鍵的,對於我們原始碼分析非常重要。 register 我們從 EchoClient 中的 connect() 方法出發,或者 E
jquery 1.7.2原始碼解析(二)構造jquery物件
構造jquery物件 jQuery物件是一個類陣列物件。 一)建構函式jQuery() 建構函式的7種用法: 1.jQuery(selector [, context ]) 傳入字串引數:檢查該字串是選擇器表示式還是HTML程式碼。如果是選擇器表示式,則遍歷文件查詢匹配的DOM元
java集合原始碼解析(二)--AbstractCollection
今天帶來的是java單列頂層介面的第一個輕量級實現:AbstractCollection 我們直接進入正題,先來看看它的宣告: package java.util; //可以從名字上同樣看到 AbstractCollection 是一個抽象類,所以並不能例項化, //這個類只是作
EventBus原始碼解析(二)—釋出事件和登出流程
1.EventBus原始碼解析(一)—訂閱過程 2.EventBus原始碼解析(二)—釋出事件和登出流程 前言 上一篇部落格已經比較詳細的講解了EventBus的註冊過程,有了上一篇部落格的基礎,其實關於EventBus的原始碼中的其他流程就非常好理解了,尤其是我
Spring原始碼解析(二):obtainFreshBeanFactory
spring的ApplicationContext容器的初始化流程主要由AbstractApplicationContext類中的refresh方法實現。 而refresh()方法中獲取新工廠的主要是由obtainFreshBeanFactory()實現的,後續的操作均是beanFactoty的進一步處理。
Java原始碼分析——java.util工具包解析(二)——HashSet、TreeSet、LinkedHashSet類解析
Set,即集合,與數學上的定義一樣,集合具有三個特點: 無序性:一個集合中,每個元素的地位都是相同的,元素之間是無序的。 互異性:一個集合中,任何兩個元素都認為是不相同的,即每個元素只能出現一次。 確定性:給定一個集
Redis5.0原始碼解析(二)----------連結串列
基於Redis5.0 連結串列提供了高效的節點重排能力, 以及順序性的節點訪問方式, 並且可以通過增刪節點來靈活地調整連結串列的長度 每個連結串列節點使用一個 adlist.h/listNode 結構來表示: //adlist.h - A generic do
ThreadPoolExecutor原始碼解析(二)
1.ThreadPoolExcuter執行例項 首先我們先看如何新建一個ThreadPoolExecutor去執行執行緒。然後深入到原始碼中去看ThreadPoolExecutor裡面使如何運作的。 public class Test { public
redis原始碼解析(二)動態字串sds基本功能函式
1. 簡介 本文繼上文基礎上,分析動態字串的功能函式,位於sds.c。由於函式較多,本篇介紹實現動態變化的基本增刪新建釋放函式。 2. 原始碼分析 sdsHdrSize()函式用於返回sdshdr的大小,主要使用sizeof()函式實現。 /*返回sds
OKHttp 3.10原始碼解析(二):攔截器鏈
本篇文章我們主要來講解OKhttp的攔截器鏈,攔截器是OKhttp的主要特色之一,通過攔截器鏈,我們可以對request或response資料進行相關處理,我們也可以自定義攔截器interceptor。 上一篇文章中我們講到,不管是OKhttp的同步請求還是非同步請求,都會呼叫RealCal
OkHttp原始碼解析(二)
上一篇講到OkHttp的整體流程,但是裡面有一個很重要的方法getResponseWithInterceptorChain還沒有講到,這個方法裡面包括了整個okHttp最重要的攔截器鏈,所以我們今天來講解一下。 Response getResponseWithI
Java容器——HashMap(Java8)原始碼解析(二)
在前文中介紹了HashMap中的重要元素,現在萬事俱備,需要刨根問底看看實現了。HashMap的增刪改查,都離不開元素查詢。查詢分兩部分,一是確定元素在table中的下標,二是確定以指定下標元素為首的具體位置。可以抽象理解為二維陣列,第一個通過雜湊函式得來,第二個下標則是連結串列或紅黑樹來得到,下面