跳到主要内容

card组件解析

最近看了一些fusion的源码,决定写一下最近看源码的一些心得; 首选说明一下我看的版本:1.17.12; 然后顺便说下,我不太确定master上是不是就是当前发行的分支,不过我看了下master上的内容card组件分割开了,不过其实功能还是那些,只不过拆分的更加细致了而言。

1.启动

进入fusion的git库,然后clone下来,运行npm i && npm run dev [模块名],比如npm run dev card,即可启动项目;

2.目录结构

因为我这里主要想先说card组件(因为这个组件比较简单,交互事件也比较少),所以先看card组件; 让我们进入根目录/src/card,大致结构如下:

image.png

index文件呢主要是用来做一些全局化配置项的,可以暂时跳过; 然后我们直接看card.jsx,首先看他引入的包: image.png

好像也没有特别难的地方,classnames包是用了设置className的,可以设置多个className,类似这样: image.png nextLocale是国际化的文件包; obj是fusion团队自己实现的一个object的扩展功能的工具类; 然后是组件的声明: image.png 和我们呢平时写的组件没有太大区别,可能多了一个displayName,propTypes和defaultProps我折叠了,这些里面注释写的很清楚,主要是组件的使用者传入的什么内容,需要拿到并且展示;

3.组件挂载

我们可以看到这个组件生命周期函数只有两个,一个是componentDidMount,一个是componentDidUpdate, 分别是组件挂载后和组件更新后会调用这两个函数,而且这两个函数里的内容也很类似,componentDidMount里调用了

this._setNeedMore();
this._setContentHeight();

而componentDidUpdate里则是只调用了

this._setContentHeight();`

其实从名字可以看出来这两个函数的作用,_setNeedMore函数就是判断是否需要展示更多的按钮,_setContentHeight则是用来设置内容区域的高度; 然后首先让我们来看_setNeedNore方法: image.png 首先从props里获取了contentHeight这个值,是从api里暴露出来的,之后调用了一个方法,获取childrenHeight的高度,入参是this.content; 我们先来看下this.content是什么: 让我们debug打印一下组件的this: image.png 可以看到content其实就是card组件的内容区域的组件,那他是怎么挂载上的呢? 这个其实就是将ref挂载到content中就好; 接下来我们继续找_getNodeChildrenHeight这个方法: image.png 可以看到,他先做了一个判断,如果node不存在的话就返回0,这个一方面是问了代码的健壮性,一方面,可能如果有人不小心在componentWillMount中调用的这个方法的话,由于这个时候还没有render,会导致拿不到ref,所以也就会导致node为空; 接下来就很简单了,他会获取到dom的内容,然后返回dom的offsetTop+上offsetHeight,我一开始试了好多次都发现offsetTop是0,后来发现这个是为了兼容如果修改了content的样式的时候,比如padding之类的内容的时候,会使高度变化; 然后回到_setNeedMore,这个方法最后返回一个state,如果contentHeight !== 'auto' 并且 content实际的高度超过设定的高度的时候就会出现更多的按钮; 接下来是_setContentHeight方法,其实大同小异: image.png 也是获取内容的高度,然后是判断state里的expand,这个呢其实就是更多那个按钮是否展开的状态,默认是false,当你点展开按钮的时候就为true,之后如果展开状态就讲高度设为最终的高度,如果是收起状态,那就是contentHeight的高度加上footer的高度(如果存在的话);

4.组件渲染

这个组件渲染还是很简单的,title是否存在,subTitle是否存在,是否展示更多按钮,还有一个样式的不同参数的时候添加一个不通的className,这部分就不在说太多了,应该仔细看下都能明白的;

总结

因为看源码的时候不太多,所以担心写的时候不清晰,所以找了一个几乎可以说是最简单的一个组件的源码来写,所以其实看起来也不太难,也没有与其他的组件有过多的交互,所以看起来还是比较轻松的,不过这个只是个入门的源码解析,主要也是给自己一个过渡,以及提供一个研究源码的思路,之后也会在研究一下比较复杂的源码,比如table的实现,from的实现,这些肯定是会比较复杂的。

Loading Comments...