① 获取用户数据的关键组件
antd中的数据录入组件,其实就是表单类组件,作为web服务获取用户输入数据的重要组件,必须考虑到其操作易用、前置校验、状态提示、风格统一等交互特性。
纵观了antd这里的一系列数据录入组件,抛开设计的角度,从技术来看,这里最重要的且复用最高的还是前面文章《读读antd源码之导航组件》提到的rc-trigger,就是提供动作监听弹出浮层的组件,基本大多数数据录入组件都会用到。
而其他的组件,基本看抽出来的组件库react-component就可以了。
② 一些基础组件
这里的 Checkbox、Input、Radio、Rate、Switch、Upload都是比较简单的基础组件,这里就不展开源码分析。
③ 一些辅助组件
这里的AutoComplete、InputNumber、Mentions、Transfer都是基于基础组件衍生出来的组件,加了一些辅助功能,源码层面也没有太大参考价值。
④ Cascader(级联选择)、Select(选择器)
这里先看一下级联选择组件,直接看到抽出来的cascader入口,看下返回结构:
这个BaseSelect引用的就是rc-select组件的基础功能,找到对应源码,可以发现其封装了一系列的事件监听和数据处理,通过基于rc-trigger封装的SelectTrigger再包一层处理。
简单来说,就是复杂一点的Select组件,有兴趣可以详细看一下rc-select组件,暂未发现值得拿出来分享的内容。
⑤ DatePicker(日期选择框)、TimePicker(时间选择框)
这里的TimePikcer为DatePicker的简化版,所以可以着重看下DatePicker,对应封装的库里的是rc-picker。
找到Picker引用的PickerPanel,可以看到它分类了很多个不同时间类型的panel:
然后根据不同类型来,加载对应组件,以decade为例:
再看看DatePanel组件,可以看到分开了两部分:
进入看下DateBody,发觉也是抽出了一个PanelBody组件,这里再看下其关键代码:
上面这块代码还是比较有参考意义的,它这里是用了table标签来显示这种纵横类数据展示,类似表格一样的数据:
而我发现很多开发者,很多时候展示这类数据,要么直接div或者ul和li,其实都比较“不正路”。
⑥ Form(表单)
表单组件,其实就是上面的基础组件配合成一个表单,再统一收录数据,关键在于处理整体form和个体之间的关系。
主要地,还是利用了 ref 特性,可以给父组件调用子组件实例的各类方法。
另外,可以关注一下,它抽出来校验相关的库:form-validation。
这里其实想看的,还是antd 3.x 版本应用的比较广泛的表单双向绑定,就像下面的应用例子:
这里用的是getFieldDecorator方法,实现了类似vue中v-model的语法糖,劫持了onChange事件,赋值给实际对应的value。
但是react和vue不一样,react不是双向数据绑定的,不能直接给value变量赋值,所以这里的更新值,实际上是利用了item的value挂载的全局form,只要知道form对应的decorator,就可以去更新对应的引用值。
这里去看一下rc-form会比较清晰,找到引用的createBaseForm组件,再搜索到getFieldDecorator函数:
这里可以首先关注下supportRef工具函数:
前面也说了,ref 对应这个form组件很重要,所以它要判断是否像类组件可以直接调用子实例方法和数据,不然的话,就要通过FieldElemWrapper包一层。
那value和onChange是在哪里处理的呢,从应用代码中可以知道,我们传入的数据录入组件,就是fieldElem变量。
而它clone出来的decoratedFieldElem引用的props,是通过getFieldProps生成的,所以再看看这个方法里面的几个地方的关键代码:
至于处理数据过程,就是通过fieldsStore方法,它又是从createFieldsStore实例出来的,详细可以看下:github.com/react-compo…,
封装了field的获取和更新的各种方法,这里不再展开,简单来说,就是操作一个大的对象的各个子数据。
其他细节也不展开。
⑦ TreeSelect(数选择)
选择器本身利用了select特性,所以这里关注的还是核心rc-tree组件。
可以先关注下子节点的实际结构、数据,或渲染效果,都有这种层级递归渲染的感觉:
这里的关键是,每个层级,需要处理为一个缩进的容器,再给子节点去递归处理,逻辑是相通的,所以感觉这里计算的逻辑可能还是比较影响渲染性能的。
基于这个预设逻辑,无意中查看了一下antd3.x和antd4.x的渲染对比,会发觉原来antd4.x做了一个优化,就是渲染方式不是层级递归的,是扁平化的。
先看看antd3.x的渲染结构:
再看看antd4.x的渲染结构:
可以通过rc-tree入口一层一层,找到依赖的NodeList,再找到以来的MotionTreeNode,最后发现了TreeNode,看下最关键的渲染部分代码:
一堆监听事件处理暂且不展开,可以看到renderDragHandler、renderSwitcher、renderCheckbox、renderSelector几个渲染的关键内容。
而在这些的前面,还有一个关键的Indent组件:
这个就是按层级来计算缩进的占位,从而实现了按层级展开的效果,而结构是平铺的。
再回头看下rc-tree的最开始的地方,你会看到一个关键组件rc-virtual-list的应用:
有兴趣可以详细展开这个虚拟列表的实现,关键它在这里的树组件中,就可以像平铺表数据那样去进行虚拟展示,在渲染上有了一个大幅度的优化提升。