摘要:结构项目结构如下,负责外层封装,负责事件绑定与渲染控制。节点通过决定事件绑定情况,即通过属性绑定事件情况,事件控制组件的属性,这里就不详细说了。为隐藏状态下的添加的,并包裹懒加载组件。
引言
antd的Tooltip组件在react-componment/trigger的基础上进行封装,而组件Popover和Popconfirm是使用Tooltip组件的进行pop,在react-componment中,使用到组件tc-trigger的还有menu、select、dropdown、time-picker、calendar等,本文主要对tc-trigger源码进行解读。
结构项目结构如下:
index.js,负责外层封装,负责事件绑定与dom渲染控制。
LazyRenderBox.js,pop内容懒加载warp。
mock.js 未使用。
Popup.js,pop的warp,负责控制pop的对齐、动画、宽高。
PopupInner.js,pop内容warp。
index.js从render方法入手,需要渲染控制pop显示的节点和pop内容节点两个节点,而pop内容节点一般渲染到body里面,不属于控制pop显示的节点内,render方法代码如下:
const trigger = React.cloneElement(child, newChildProps); if (!IS_REACT_16) { return ({({ renderComponent }) => { this.renderComponent = renderComponent; return trigger; }} ); } let portal; // prevent unmounting after it"s rendered if (popupVisible || this._component || props.forceRender) { portal = ({this.getComponent()} ); } return [ trigger, portal, ];
可以看到,index.js渲染了两个节点,trigger和portal,trigger即为通过事件控制portal显示状态的节点,如果react的版本不是16以上,返回ContainerRender组件,ContainerRender组件来自rc-util,该组件主要做的事情就是使用ReactDOM.unstable_renderSubtreeIntoContainer函数,将pop内容渲染到trigger节点之外,与react16提供的APIcreatePortal作用一致,如果是React16,返回了Portal组件,该组件正是利用了createPortal,将组件渲染到特定的dom节点内,但是不管是不是react16,都进行了pop渲染的判断,即popupVisible || this._component || props.forceRender,如果portal不显示且不强制第一次渲染forceRender,portal将不会被渲染到dom中,直到判断为真。
trigger节点通过props决定事件绑定情况,即通过props.trigger属性绑定事件情况,事件控制Popup组件的visible属性,这里就不详细说了。
Popup.js该组件是pop的warp,渲染在trigger节点之外,通过ReactDOM.unstable_renderSubtreeIntoContainer或createPortal指定渲染的目标节点,也是render方法入手:
render() { return ({this.getMaskElement()} {this.getPopupElement()}); }
返回两个内容,getMaskElement获取遮罩,getPopupElement返回Pop节点,getMaskElement这里就不说了,渲染的视觉效果,绑定了控制pop节点的事件。
getPopupElement返回pop节点,render返回代码如下:
{children}
Animate来自组件rc-animate,主要负责显示状态切换时候的动态效果,其中原理是监听控制状态变化的prop属性,即代码中的showProp="xVisible",当状态变化的时候,延时改变dom的class,一般会有三个状态,分别表示进入中enter-active,消失中leave-active,隐藏hidden三个状态,进入中状态会添加transitionName-enter transitionName-enter-active两个class,消失中会添加transitionName-leave transitionName-leave-active两个class,隐藏状态不添加class,transitionName通过外部传入。
Align来自组件rc-align,主要控制节点的相对于trigger的显示位置,根据传入的target与align决定最后PopupInner显示的位置,此处target是来自于index.js的trigger节点,align也是来自于index.js,主要由index.js的prop.popupPlacement、prop.popupAlign两个属性决定,即方向与偏移量。
最后是PopupInner组件,该组件是也就pop内容组件,内容通过LazyRenderBox包裹。。。
另外,Popup.js还有两个state,targetWidth与targetHeight,即pop的宽高,该属性如果设置有prop.stretch,则计算trigger真是dom节点的宽高,然后对齐。
PopupInner.js为隐藏状态下的pop添加hidden的class,并包裹懒加载组件LazyRenderBox。
LazyRenderBox.js只做一件事情,就是将popupInner的chidren进行包裹,当子节点数大于1时,包一层div以方便隐藏状态时候class控制,不用每个节点都添加hidden的class,关键如下:
render() { const { hiddenClassName, visible, ...props } = this.props; if (hiddenClassName || React.Children.count(props.children) > 1) { if (!visible && hiddenClassName) { props.className += ` ${hiddenClassName}`; } return ; } return React.Children.only(props.children); }最后
该组件主要的实现难点在于rc-animate与rc-align,其他的主要在做事件绑定与class处理。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/107737.html
摘要:引言看过源码的都知道,其实是在一组组件的基础上进行了一层封装,本文主要解读组件的基础组件,另外会略过模式下的代码。解读源码首先要从自己最常用的或者感兴趣的入手,首先组件最主要的还是在这个装饰器入手。 引言 看过antd源码的都知道,antd其实是在一组react-componment组件的基础上进行了一层ui封装,本文主要解读antd组件Form的基础组件react-componmen...
摘要:作为开发当中使用相对频繁的一个组件,其实现也很简单,但是其中比较麻烦的一部分是字体的制作,可以参看这篇文章。接口中的种属性方法,不属于上述六种。为事件属性,可以大家也可以根据上面所提供的制作的方法和这样的方式来实现自己的组件 Icon icon作为开发当中使用相对频繁的一个组件,其实现也很简单,但是其中比较麻烦的一部分是icon字体的制作,可以参看这篇文章。 Antd的Icon组件使用...
github: 地址gitbook: 地址 Index.js 看一个代码的时候首先当然是从他的入口文件开始看起,所以第一份代码我们看的是/index.js文件 开始 打开index.js文件,代码只有28行,其中包含了一个camelCase函数(看函数名就知道这是个给名称进行驼峰命名法的函数),一个req变量,以及这个的变量操作和export操作 在这个文件里面我首先查了require.conte...
摘要:这个组件是一个图钉组件,使用的布局,让组件固定在窗口的某一个位置上,并且可以在到达指定位置的时候才去固定。 Affix 这个组件是一个图钉组件,使用的fixed布局,让组件固定在窗口的某一个位置上,并且可以在到达指定位置的时候才去固定。 AffixProps 还是老样子,看一个组件首先我们先来看看他可以传入什么参数 // Affix export interface Affix...
Button Button包括了两个组件,Button与ButtonGroup。 ButtonProps 看一个组件首先看的是他的传参也就是props,所以我们这里先看Button组件的ButtonProps export type ButtonType = primary | ghost | dashed | danger; export type ButtonShape = circl...
阅读 2591·2021-11-18 10:02
阅读 3391·2021-09-22 15:50
阅读 2319·2021-09-06 15:02
阅读 3538·2019-08-29 16:34
阅读 1661·2019-08-29 13:49
阅读 1242·2019-08-29 13:29
阅读 3592·2019-08-28 18:08
阅读 2892·2019-08-26 11:52