antd源码解析(二)button控件的解析

来源:互联网 发布:淘宝店铺如何取消分流 编辑:程序博客网 时间:2024/06/05 07:06

第一节我们看了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',      ....

这个就不用解释了,其实就是定义了相应的函数而已。