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',
      ....

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值