摘要:結構項目結構如下,負責外層封裝,負責事件綁定與渲染控制。節點通過決定事件綁定情況,即通過屬性綁定事件情況,事件控制組件的屬性,這里就不詳細說了。為隱藏狀態下的添加的,并包裹懶加載組件。
引言
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處理。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/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...
閱讀 2672·2021-11-18 10:02
閱讀 3437·2021-09-22 15:50
閱讀 2365·2021-09-06 15:02
閱讀 3584·2019-08-29 16:34
閱讀 1751·2019-08-29 13:49
閱讀 1281·2019-08-29 13:29
閱讀 3644·2019-08-28 18:08
閱讀 2945·2019-08-26 11:52