国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

解讀React源碼(二):Virtual DOM模型

kuangcaibao / 1671人閱讀

摘要:模型模型負(fù)責(zé)底層框架的構(gòu)建工作它擁有一整套的標(biāo)簽并負(fù)責(zé)虛擬節(jié)點(diǎn)及其屬性的構(gòu)建更新刪除等工作其實(shí)構(gòu)建一套簡(jiǎn)易模型并不復(fù)雜它只需要具備一個(gè)標(biāo)簽所需的基本元素即可標(biāo)簽名屬性樣式子節(jié)點(diǎn)唯一標(biāo)識(shí)中的節(jié)點(diǎn)稱為它分為種類型其中又分為和創(chuàng)建元素輸入輸出通過(guò)

Virtual DOM模型

1.Virtual DOM模型負(fù)責(zé)Virtual DOM底層框架的構(gòu)建工作,它擁有一整套的Virtual DOM標(biāo)簽,
并負(fù)責(zé)虛擬節(jié)點(diǎn)及其屬性的構(gòu)建,更新,刪除等工作.
2.其實(shí),構(gòu)建一套簡(jiǎn)易Virtual DOM模型并不復(fù)雜,它只需要具備一個(gè)DOM標(biāo)簽所需的基本元素即可.

{
    // 標(biāo)簽名
    tagName: "div",
    // 屬性
    properties: {
        // 樣式
        style: {}
    },
    // 子節(jié)點(diǎn)
    children: [],
    // 唯一標(biāo)識(shí)
    key: 1
}

3.Virtual DOM中的節(jié)點(diǎn)稱為ReactNode,它分為3種類型:ReactElement,ReactFragment,ReactText.
其中,ReactElement又分為ReactComponentElement和ReactDOMElement.

創(chuàng)建React元素
// 輸入jsx
const app = ;

// 輸出js
const app = React.createElement(
    Nav,
    {color: "blue"},
    React.createElement(Profile, null, "click")
);

通過(guò)jsx創(chuàng)建的虛擬元素最終會(huì)被編譯成調(diào)用React的createElement方法

// createElement只是做了簡(jiǎn)單修正,返回一個(gè)ReactElement實(shí)例對(duì)象
// 也就是虛擬元素的實(shí)例
ReactElement.createElement = function(type, config, children) {
    // 初始化參數(shù)
    var propName;
    var props = {};
    var key = null;
    var ref = null;
    var self = null;
    var source = null;

    // 如果存在config,則提取里面的內(nèi)容
    if (config != null) {
        ref = config.ref === undefined ? null : config.ref;
        key = config.key === undefined ? null : "" + config.key;
        self = config._self === undefined ? null : config._self;
        source = config._source === undefined ? null : config._source;
        // 復(fù)制config里的內(nèi)容到props(id和className等)
        for (propName in config) {
            if (config.hasOwnProperty(propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
                props[propName] = config[propName];
            }
        }
    }

    // 處理children,全部掛載到props的children屬性上,如果只有一個(gè)參數(shù),直接賦值給children
    // 否則做合并處理
    var childrenLength = arguments.length - 2;
    if (childrenLength === 1) {
        props.children = children;
    } else if (childrenLength > 1) {
        var childArray = Array(childrenLength);
        for (var i = 0; i < childrenLength; i++) {
            childArray[i] = arguments[i + 2];
        }
        props.children = childArray;
    }

    // 如果某個(gè)prop為空且存在默認(rèn)的prop,則將默認(rèn)prop賦給當(dāng)前的prop
    if (type && type.defaultProps) {
        var defaultProps = type.defaultProps;
        for (propName in defaultProps) {
            if (typeof props[propName] === "undefined") {
                props[propName] = defaultProps[propName]
            }
        }
    }

    // 返回一個(gè)ReactElement實(shí)例對(duì)象
    return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
}
初始化組件入口

1.當(dāng)使用React創(chuàng)建組件時(shí),首先會(huì)調(diào)用instantiateReactComponent,這就是初始化組件的入口函數(shù),
它通過(guò)判斷node類型來(lái)區(qū)分不同組件的入口.

// 初始化組件入口
function instantiateReactComponent(node, parentCompositeType) {
    var instance;

    // 空組件 (ReactEmptyComponent)
    if (node === null || node === false) {
        instance = ReactEmptyComponent.create(instantiateReactComponent);
    }

    if (typeof node === "object") {
        var element = node;
        if (typeof element.type === "string") {
            // DOM標(biāo)簽 (ReactDOMComponent)
            instance = ReactNativeComponent.createInternalComponent(element);
        } else if (isInternalComponentType(element.type)) {
            // 不是字符串表示的自定義組件暫無(wú)法使用,此處將不做組件初始化操作
            instance = new element.type(element);
        } else {
            // 自定義組件
            instance = new ReactCompositeComponentWrapper();
        }
    } else if (typeof node === "string" || typeof node === "number") {
        // 字符串或數(shù)字
        instance = ReactNativeComponent.createInstanceForText(node);
    } else {
        // 不做處理
    }

    // 設(shè)置實(shí)例
    instance.construct(node);
    // 初始化參數(shù)
    instance._mountIndex = 0;
    instance._mountImage = null;

    return instance;
}
文本組件

1.當(dāng)node類型為文本節(jié)點(diǎn)時(shí)是不算Virtual DOM元素的,但React為了保持渲染的一致性,
將其封裝為文本組件ReactDOMTextComponent.

DOM標(biāo)簽組件

1.Virtual DOM模型涵蓋了幾乎所有的原生DOM標(biāo)簽,如

,

,等.
當(dāng)開(kāi)發(fā)者使用React時(shí),此時(shí)的

并不是原生的
標(biāo)簽,他其實(shí)是React生成的
Virtual DOM對(duì)象,只不過(guò)標(biāo)簽名稱相同罷了.

_createOpenTagMarkupAndPutListeners: function(transaction, props) {
    var ret = "<" + this._currentElement.type;
    // 拼湊出屬性
    for (var propKey in props) {
        var propValue = props[propKey];

        if (registrationNameModules.hasOwnProperty(propKey)) {
            // 針對(duì)當(dāng)前的節(jié)點(diǎn)添加事件代理
            if (propValue) {
                enqueuePutListener(this, propKey, propValue, transaction);
            }
        } else {
            if (propKey === STYLE) {
                if (propValue) {
                    // 合并樣式
                    propValue = this._previousStyleCopy = Object.assign({}, props.style);
                }
                propValue = CSSPropertyOperations.createMarkupForStyles(propValue, this);
            }
            // 創(chuàng)建屬性標(biāo)識(shí)
            var markup = null;
            if (this._tag != null && isCustomComponent(this._tag, props)) {
                markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
            }
            if (markup) {
                ret += " " + markup;
            }
        }
    }
    // 對(duì)于靜態(tài)頁(yè)面,不需要設(shè)置react-id,這樣可以節(jié)省大量字節(jié)
    if (transaction.renderToStaticMarkup) {
        return ret;
    }
    // 設(shè)置reactid
    if (!this._nativeParent) {
        ret += " " + DOMPropertyOperations.createMarkupForRoot();
    }
    ret += " " + DOMPropertyOperations.createMarkupForID(this._domID);

    return ret;
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/84660.html

相關(guān)文章

  • 解讀React源碼(一):初探React源碼

    摘要:前言的基本概念組件的構(gòu)建方法以及高級(jí)用法這背后的一切如何運(yùn)轉(zhuǎn)深入內(nèi)部的實(shí)現(xiàn)機(jī)制和原理初探源碼代碼組織結(jié)構(gòu)包含一系列的工具方法插件包含一系列同構(gòu)方法包含一些公用或常用方法如等包含一些測(cè)試方法等包含一些邊界錯(cuò)誤的測(cè)試用例是代碼的核心部分它包含了 前言 React的基本概念,API,組件的構(gòu)建方法以及高級(jí)用法,這背后的一切如何運(yùn)轉(zhuǎn),深入Virtual DOM內(nèi)部的實(shí)現(xiàn)機(jī)制和原理. 初探Rea...

    Eminjannn 評(píng)論0 收藏0
  • React 源碼深度解讀(一):首次DOM元素渲染 - Part 1

    摘要:調(diào)用棧是這樣的這里生成的我們將其命名為,它將作為參數(shù)傳入到。整個(gè)的調(diào)用棧是這樣的組件間的層級(jí)結(jié)構(gòu)是這樣的到此為止,頂層對(duì)象已經(jīng)構(gòu)造完畢,下一步就是調(diào)用來(lái)自的方法,進(jìn)行頁(yè)面的渲染了。通過(guò)表達(dá)的結(jié)構(gòu)最終會(huì)轉(zhuǎn)化為一個(gè)純對(duì)象,用于下一步的渲染。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言...

    daydream 評(píng)論0 收藏0
  • React 源碼深度解讀):首次 DOM 元素渲染 - Part 2

    摘要:本文將要講解的調(diào)用棧是下面這個(gè)樣子的平臺(tái)無(wú)關(guān)相關(guān)如果看源碼,我們會(huì)留意到很多相關(guān)的代碼,我們暫時(shí)先將其忽略,會(huì)在后續(xù)的文章中進(jìn)行講解。現(xiàn)在我們來(lái)看一下各實(shí)例間的關(guān)系目前為止的調(diào)用棧平臺(tái)無(wú)關(guān)相關(guān)下一篇講解三總結(jié)本文講解了轉(zhuǎn)化為的過(guò)程。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 R...

    wean 評(píng)論0 收藏0
  • React 源碼深度解讀(九):?jiǎn)蝹€(gè)元素更新

    摘要:作為聲明式的框架,接管了所有頁(yè)面更新相關(guān)的操作。是用于內(nèi)部操作的實(shí)例,這里將它的初始化為空數(shù)組并插入一個(gè)新的。連續(xù)次后,期望的結(jié)果應(yīng)該是。原因很簡(jiǎn)單,因?yàn)榇蔚臅r(shí)候,取到的都是在完后不會(huì)同步更新。 前言 React 是一個(gè)十分龐大的庫(kù),由于要同時(shí)考慮 ReactDom 和 ReactNative ,還有服務(wù)器渲染等,導(dǎo)致其代碼抽象化程度很高,嵌套層級(jí)非常深,閱讀其源碼是一個(gè)非常艱辛的過(guò)程...

    kid143 評(píng)論0 收藏0
  • React 源碼深度解讀(十):Diff 算法詳解

    摘要:的做法比較簡(jiǎn)單,它會(huì)先刪除整個(gè)子樹(shù),然后再重新創(chuàng)建一遍。同樣道理,當(dāng)節(jié)點(diǎn)改為節(jié)點(diǎn)時(shí),整棵子樹(shù)也會(huì)被刪掉,節(jié)點(diǎn)會(huì)重新創(chuàng)建。更新為和中較大的。到此為止,整個(gè)源碼解讀系列先告一段落了,后會(huì)有期。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 React 是一個(gè)十分龐大的庫(kù),由于要同時(shí)考慮...

    sutaking 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

kuangcaibao

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<