阅读版本:antd 3+
time: 2018.8.06
为什么要阅读源码?要解决些什么问题?自己想要一些什么收获?怎么阅读
目录
- 为什么要阅读源码?
- 要解决些什么问题?
- 怎么阅读?
- 归纳总结
想要深入了解这个产品,因为它在我日常项目中用到非常多,github 上已经超过 3w star,深入学习了解它对我个人的帮助是很大的
源码中有些接口是没有对外暴露的,这样学习可以寻找到一些隐藏的接口信息
- antd 是如何设计的?它的设计价值观、设计原则及设计模式是怎样的?
- 它是如何组织自己的开源项目的?有什么值得学习借鉴并改进的地方?我要做怎么做?
- 学习它的组件化开发思想,html, css, js, react 配合使用技巧总结
入口:官网
总结:该文档
应用:hyj-base
antd 基于
确定
和自然
的设计价值观,通过模块化的解决方案,降低冗余的生产成本,让设计者专注于更好的用户体验
问:设计价值观有哪些?分别代表什么含义
设计价值观:用于判断设计好坏的内在标准。这个标准又是什么?按照有效设计实践遵循规则,提供具体设计问题的向导和一般解决方案
视觉系统为主:通过提炼自然界的客观规律,并运用到界面设计中,创建更有层次的产品体验
后期加入听觉系统、触觉系统等,创建多维、更真实的产品体验
行为执行:辅助用户有效决策、减少用户的额外操作,节省用户脑力和体力,让人机交互更为自然
优秀的产品研发状态:高确定性、低熵值
- 保持克制:聚焦在最有价值的产品功能打磨,并用尽可能少的设计元素将其表达,有的能做但是选择不做。完美不在于无以附加,而在于无可删减。
- 面向对象:抽象对象,增强界面设计的灵活性和可维护性,减少设计者的主观干扰,降低系统的不确定性,就是降低熵值。
- 模块化设计:通用模块抽象,提供有限接口与其他模块互动,最终减少系统的复杂度,进而增强可靠性及可维护性
问题:这里存在一个过度封装,比如我想用其中一个组件,组件能满足我大部分的需求使用,但是有一小点,我要对其做一点个性化的设计,而antd又没有提供对应的接口,那么我就可能需要做些强制性样式或功能修改,很可能去动源码
阅读完官网的所有信息,包含设计语言、组件,组件下的快速上手、cli脚手架、主题、国际化等,开始了我的组件源码阅读,转战github
clone ant-design ,npm install, npm start,运行的效果跟官网的一样,就可以调试以及查看组件源码
antd源码阅读注意事项
- 网页是由
md
文件构建 - 组件是用
ts
+less
构建 - 使用
tsx
: typescript 的 jsx @types/react
:npm install -S react @types/react
,这里是额外获取的 react 的声明文件- 使用
tsconfig.json
配置文件,可以使用awesome-typescript-loader
配合 webpack 使用
入口:Button 组件
作为入口
import Button from './button';
import ButtonGroup from './button-group';
export { ButtonProps, ButtonShape, ButtonSize, ButtonType } from './button';
export { ButtonGroupProps } from './button-group';
Button.Group = ButtonGroup;
export default Button;
同时支持 export 及 export default
在看到 tsx 的时候,有的东西看不懂,然后就去学习 ts 。antd 内部 ts 配置是在 const getWebpackConfig = require('antd-tools/lib/getWebpackConfig');
antd-tools 这个 npm 包里面的配置
components/style/themes/default.less
全局默认配置样式,这里面分模块端定义样式变量,包括 colors, font, padding, border, icon, link, animation, outline, disableStates, shadow, buttons, checkbox, radio, radioButtons, mediaQueries, grid, layout, zIndex, form, input, toolTip, popover, modal, progress, menu, darkTheme, spin, table, tag, timePicker, carousel, badge, rate, card, tabs, backtop, avatar, switch, pagination, breadcrumb, slider, tree, collapse, messagecomponents/style/mixins/index.less
里面都是 less 函数式(混合)的写法,包括 size, square, reset, motion, iconfont, clearfix, placeholder./mixin.less
全是为 button 定制的 mixin./index.less
button 主要样式
我这里不学习它的颜色计算面的知识,具体在 components/style/color/colorPalette.less 中,里面有使用 less function 等
4.2.4.1 Button className
// 变量作为 key,使用 [string]: value
// 模板字符串,使用 `${}`
const classes = classNames(prefixCls, className, {
[`${prefixCls}-${type}`]: type,
[`${prefixCls}-${shape}`]: shape,
[`${prefixCls}-${sizeCls}`]: sizeCls,
[`${prefixCls}-icon-only`]: !children && icon,
[`${prefixCls}-loading`]: loading,
[`${prefixCls}-clicked`]: clicked,
[`${prefixCls}-background-ghost`]: ghost,
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar,
});
4.2.4.2 Button jsx
根据是否传入 href
属性,判断是否是超链接还是按钮
if ('href' in rest) {
return (
<a
{...rest}
className={classes}
onClick={this.handleClick}
>
{iconNode}{kids}
</a>
);
} else {
const { htmlType, ...otherProps } = rest;
return (
<button
{...otherProps}
type={htmlType || 'button'}
className={classes}
onClick={this.handleClick}
>
{iconNode}{kids}
</button>
);
}
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
import { findDOMNode } from 'react-dom';
// Fix for HOC usage like <FormatMessage />
const node = (findDOMNode(this) as HTMLElement);
const buttonText = node.textContent || node.innerText;
findDOMNode
:使用 ReactDOM 提供的这个方法
node.textContent || node.innerText
:使用 textContent ,会返回当前节点及其所有子节点的文本内容,包含 script 内部
为什么不用 innerText ?答:因为访问这个属性虽然不会获取到 script 内容,但是它会强制浏览器触发重绘
- Button 组件
prefixCls
prop: 最好不改,默认 ant-btn ;改了可以自定义样式
- 组件设计模式:原来这些庞大的开源项目开发的组件,也跟我自己做项目设计的组件一样的:通过 props 控制组件、预定义 less 变量、有状态与无状态组件、默认 props 与 默认 state
- 自己需要解决的问题:px em 异同;letter-spacing word-spacing;防抖与节流