最近更新有点慢,更新慢的原因最近在看

  • 《css世界》这本书,感觉很不错

  • 《JavaScript高级程序设计》 这本书已经看了很多遍了,主要是复习前端的基础知识,基础知识经常会过一段时间记忆就会慢慢模糊,特别是现在用vue、react、angularjs已经很少用原生js了,对dom的原生api方法已经忘记很多了。

  • 《梦的解析》--弗洛伊德,看这本书主要是自己的兴趣爱好,里面的内容有点难度,想通过心理学改变自己,做更好更真实的自己。

题外话说完了,这篇主要是针对上一篇对ant of react的代码解析只是加了注释反应很难懂,没有那么时间去一个一个仔细看。后面ant发布了新版本在button组件上对动画效果做了一些处理,大概的逻辑结构没变。这篇就用思维导图来展示下ant of react button组件js代码的逻辑结构,画的不好敬请谅解。

结构主线

按钮的代码逻辑结构的主线其实就是围绕按钮对外开放的功能实现的,所有我想来看看ant desgin of ract 按钮组件对外开放的功能导图:

  • disabled 按钮失效状态

  • ghost 幽灵属性

  • href 点击跳转的地址,指定此属性 button 的行为和 a 链接一致

  • htmlType 设置 button 原生的 type 值,可选值请参考 HTML 标准

  • icon 设置按钮的图标类型

  • loading 设置按钮载入状态

  • shape 设置按钮形状

  • size 设置按钮大小

  • target 相当于 a 链接的 target 属性,href 存在时生效

  • type 设置按钮类型,可选值为 primary dashed danger(版本 2.7 中增加) 或者不设

  • onClick 点击按钮时的回调

  • block 将按钮宽度调整为其父宽度的选项

其中导致组件html结构不一样的是href功能,所以先看href的实现

   /**
* 组件内容
*/
render() {
const {
type, shape, size, className, children, icon, prefixCls, ghost, loading: _loadingProp, block, ...rest
} = this.props; const { loading, hasTwoCNChar } = this.state; // large => lg
// small => sm
let sizeCls = '';
switch (size) {
case 'large':
sizeCls = 'lg';
break;
case 'small':
sizeCls = 'sm';
default:
break;
} const now = new Date();
const isChristmas = now.getMonth() === 11 && now.getDate() === 25;
/**
* 拼接className
*/
const classes = classNames(prefixCls, className, {
[`${prefixCls}-${type}`]: type,//对应type功能
[`${prefixCls}-${shape}`]: shape,//对应shape功能
[`${prefixCls}-${sizeCls}`]: sizeCls,//对应size功能
[`${prefixCls}-icon-only`]: !children && icon,//对应icon功能
[`${prefixCls}-loading`]: loading,//对应loading功能
[`${prefixCls}-background-ghost`]: ghost,//对应ghost功能
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar,
[`${prefixCls}-block`]: block,//对应block功能
christmas: isChristmas,
});
/**
* 设置图标
*/
const iconType = loading ? 'loading' : icon;
const iconNode = iconType ? <Icon type={iconType} /> : null;
const kids = (children || children === 0)
? React.Children.map(children, child => insertSpace(child, this.isNeedInserted())) : null; const title = isChristmas ? 'Ho Ho Ho!' : rest.title;
/**
* 判断是a标签还是button标签,对应href功能
*/
if ('href' in rest) {
return (
<a
{...rest}
className={classes}
onClick={this.handleClick}
title={title}
>
{iconNode}{kids}
</a>
);
} else {
// React does not recognize the `htmlType` prop on a DOM element. Here we pick it out of `rest`.
const { htmlType, ...otherProps } = rest; return (
<Wave>
<button
{...otherProps}
type={htmlType || 'button'}
className={classes}
onClick={this.handleClick}
title={title}
>
{iconNode}{kids}
</button>
</Wave>
);
}
}

上面的那些功能配置属性是通过父组件通过props传递进来的,那组件代码中要有接收参数已经检验参数类型的处理块:

/**
* 类型别名,这个类型的只能是对应的值
*/
export type ButtonType = 'default' | 'primary' | 'ghost' | 'dashed' | 'danger';
export type ButtonShape = 'circle' | 'circle-outline';
export type ButtonSize = 'small' | 'default' | 'large';
export type ButtonHTMLType = 'submit' | 'button' | 'reset';
/**
* 声明一个接口BaseButtonProps
*/
export interface BaseButtonProps {
type?: ButtonType;
icon?: string;
shape?: ButtonShape;
size?: ButtonSize;
loading?: boolean | { delay?: number };
prefixCls?: string;
className?: string;
ghost?: boolean;
block?: boolean;
children?: React.ReactNode;
}
/**
* a标签的参数组合
*/
export type AnchorButtonProps = {
href: string;
target?: string;
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
} & BaseButtonProps & React.AnchorHTMLAttributes<HTMLAnchorElement>;
/**
* button标签的参数组合
*/
export type NativeButtonProps = {
htmlType?: ButtonHTMLType;
onClick?: React.MouseEventHandler<HTMLButtonElement>;
} & BaseButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>;
/**
* 类型别名
*/
export type ButtonProps = AnchorButtonProps | NativeButtonProps;
/**
* button class声明
*/
export default class Button extends React.Component<ButtonProps, any> {
static Group: typeof Group;
static __ANT_BUTTON = true;
/**
* 设置props默认值
*/
static defaultProps = {
prefixCls: 'ant-btn',
loading: false,
ghost: false,
block: false,
};
/**
* props类型校验
*/
static propTypes = {
type: PropTypes.string,
shape: PropTypes.oneOf(['circle', 'circle-outline']),
size: PropTypes.oneOf(['large', 'default', 'small']),
htmlType: PropTypes.oneOf(['submit', 'button', 'reset']),
onClick: PropTypes.func,
loading: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
className: PropTypes.string,
icon: PropTypes.string,
block: PropTypes.bool,
};

这段代码大概意思是在typescript中声明接口和自定义类型来校验参数对象里面的键值对的数据类型,defaultProps设置参数的某些默认值,propTypes在react中通过prop-types来校验参数的数据量类型和值。

剩下就是单击事件和组件声明周期的一些处理事件

  • 组件的构造函数 声明state的值
  /**
* 构造函数
*/
constructor(props: ButtonProps) {
super(props);
this.state = {
loading: props.loading,
hasTwoCNChar: false,
};
}
  • 单击事件,如果是加载状态不触发单击事件
  /**
* 单击事件
*/
handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => {
const { loading } = this.state;
const { onClick } = this.props;
if (!!loading) {
return;
}
if (onClick) {
(onClick as React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>)(e);
}
}
  • 组件的生命周期处理
 /**
* 组件渲染之后调用,只调用一次。
*/
componentDidMount() {
this.fixTwoCNChar();
}
/**
* props改变时调用触发,nextProps.loading赋值到setState的loading
* @param nextProps
*/
componentWillReceiveProps(nextProps: ButtonProps) {
const currentLoading = this.props.loading;
const loading = nextProps.loading; if (currentLoading) {
clearTimeout(this.delayTimeout);
} if (typeof loading !== 'boolean' && loading && loading.delay) {
this.delayTimeout = window.setTimeout(() => this.setState({ loading }), loading.delay);
} else {
this.setState({ loading });
}
}
/**
* 组件更新完成后调用
*/
componentDidUpdate() {
this.fixTwoCNChar();
}
/**
* 组件将要卸载时调用,清除定时器
*/
componentWillUnmount() {
if (this.delayTimeout) {
clearTimeout(this.delayTimeout);
}
}
/**
* 判断botton的内容是否有两个中文字
*/
fixTwoCNChar() {
// Fix for HOC usage like <FormatMessage />
const node = (findDOMNode(this) as HTMLElement);
const buttonText = node.textContent || node.innerText;
if (this.isNeedInserted() && isTwoCNChar(buttonText)) {
if (!this.state.hasTwoCNChar) {
this.setState({
hasTwoCNChar: true,
});
}
} else if (this.state.hasTwoCNChar) {
this.setState({
hasTwoCNChar: false,
});
}
}
/**
* 判断是否是字符串类型
*/
function isString(str: any) {
return typeof str === 'string';
}
/**
* 多个中文间插入空格
* @param {Object} child 组件的子内容
* @param {Boolean} needInserted 是否插入空格
* @returns {ReactElement}
*/
// Insert one space between two chinese characters automatically.
function insertSpace(child: React.ReactChild, needInserted: boolean) {
// Check the child if is undefined or null.
if (child == null) {
return;
}
const 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 <span>{child}</span>;
}
return child;
}

button JS篇ant Design of react之二的更多相关文章

  1. button JS篇ant Design of react

    这篇看ant Desgin of react的button按钮的js代码,js代码部分是typescript+react写的. button组件里面引用了哪些组件: import * as React ...

  2. ElementUI(vue UI库)、iView(vue UI库)、ant design(react UI库)中组件的区别

    ElementUI(vue UI库).iView(vue UI库).ant design(react UI库)中组件的区别: 事项 ElementUI iView ant design 全局加载进度条 ...

  3. 同时使用 Ant Design of React 中 Mention 和 Form

    使用场景,在一个列表中,点击每一行会弹出一个表单,通过修改表单数据并提交来修改这一行的数据,其中某个数据的填写需要通过Mention实现动态提示及自动补全的功能. 具体效果为: 遇到的问题: 1.希望 ...

  4. Ant Design of React 框架使用总结1

    一.  为什么要用UI 框架 统一了样式交互动画 . Ui框架会对样式,交互动画进行统一,保证了系统风格完整统一,不像拼凑起来的. 兼容性 ,不是去兼容IE 6 7 8那些低版本浏览器,而是对主流的标 ...

  5. ant design pro (十二)advanced UI 测试

    一.概述 原文地址:https://pro.ant.design/docs/ui-test-cn UI 测试是项目研发流程中的重要一环,有效的测试用例可以梳理业务需求,保证研发的质量和进度,让工程师可 ...

  6. 和我一起,重零开始学习Ant Design Pro开发解决方案(二)部署示例项目

  7. 十九、React UI框架Antd(Ant Design)的使用——及react Antd的使用 button组件 Icon组件 Layout组件 DatePicker日期组件

    一.Antd(Ant Design)的使用:引入全部Css样式 1.1 antd官网: https://ant.design/docs/react/introduce-cn 1.2 React中使用A ...

  8. React + Ant Design网页,配置

    第一个React + Ant Design网页(一.配置+编写主页) 引用博主的另外一篇VUE2.0+ElementUI教程, 请移步:  https://blog.csdn.net/u0129070 ...

  9. Vue.js高效前端开发 • 【Ant Design of Vue框架基础】

    全部章节 >>>> 文章目录 一.Ant Design of Vue框架 1.Ant Design介绍 2.Ant Design of Vue安装 3.Ant Design o ...

随机推荐

  1. 多线程工具类:CountDownLatch、CyclicBarrier、Semaphore、LockSupport

    ◆CountDownLatch◆ 假如有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以.比如你想要买套房子,但是呢你现在手上没有钱.你得等这个月工资发了.然后年终奖发了.然后朋友借你得钱 ...

  2. 2019-中小型公司PHP面试题目记录(附带答案)

    博主是三线省会城市的苦逼技术开发,主攻PHP方向,平时前后端语言也都有涉及,因为都是自学,上手就是框架,工作五年来基础补的不稳,换工作的时候苦不堪言,感觉一上来就问Ngnix的运行机制,php的被编译 ...

  3. 网络协议 16 - DNS 协议:网络世界的地址簿

    [前五篇]系列文章传送门: 网络协议 11 - Socket 编程(下):眼见为实耳听为虚 网络协议 12 - HTTP 协议:常用而不简单 网络协议 13 - HTTPS 协议:加密路上无尽头 网络 ...

  4. Mybatis之旅第三篇-SqlMapConfig.xml全局配置文件解析

    一.前言 刚换工作,为了更快的学习框架和了解业务,基本每天都会加班,导致隔了几天没有进行总结,心里总觉得不安,工作年限越长越感到学习的重要性,坚持下去!!! 经过前两篇的总结,已经基本掌握了mybat ...

  5. Unity资源打包学习笔记(二)、如何实现高效的unity AssetBundle热更新

    转载请标明出处:http://www.cnblogs.com/zblade/ 0x01 目的 在实际的游戏开发中,对于游戏都需要进行打补丁的操作,毕竟,测试是有限的,而bug是无法预估的.那么在手游中 ...

  6. 学习ASP.NET Core Razor 编程系列十八——并发解决方案

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  7. 制造业物料清单BOM、智能文档阅读、科学文献影响因子、"Celebrated Italian mathematician ZepartzatT Gozinto" 与 高津托图

    意大利数学家Z.高津托 意大利伟大数学家Sire Zepartzatt Gozinto的生卒年代是一个谜[1],但是他发明的 “高筋图” 在 制造资源管理.物料清单(BOM)管理.智能阅读.科学文献影 ...

  8. 谈谈我理解的SA——Systems Architecture

    什么是SA? SA即Systems Architecture,是系统体系结构. 系统体系结构是定义系统的结构.行为和系统视图的概念模型.架构师将其系统的形式化描述或表示出来,以支持结构和行为的推理的方 ...

  9. angr学习

    0.资料 几个主要的网站 angr的github:https://github.com/angr angr的document:https://docs.angr.io/ angr的api:https: ...

  10. sublime text3插件解决输入法不跟随的问题

    快捷键ctrl + shift +p 输入  install package 回车,调出插件搜索器, 在搜索栏中输入 IMESupport 回车安装插件. 即可解决问题.