成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

kuangcaibao / 1674人閱讀

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

Virtual DOM模型

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

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

3.Virtual DOM中的節(jié)點稱為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")
);

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

// createElement只是做了簡單修正,返回一個ReactElement實例對象
// 也就是虛擬元素的實例
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;
        // 復制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屬性上,如果只有一個參數(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;
    }

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

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

1.當使用React創(chuàng)建組件時,首先會調(diào)用instantiateReactComponent,這就是初始化組件的入口函數(shù),
它通過判斷node類型來區(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標簽 (ReactDOMComponent)
            instance = ReactNativeComponent.createInternalComponent(element);
        } else if (isInternalComponentType(element.type)) {
            // 不是字符串表示的自定義組件暫無法使用,此處將不做組件初始化操作
            instance = new element.type(element);
        } else {
            // 自定義組件
            instance = new ReactCompositeComponentWrapper();
        }
    } else if (typeof node === "string" || typeof node === "number") {
        // 字符串或數(shù)字
        instance = ReactNativeComponent.createInstanceForText(node);
    } else {
        // 不做處理
    }

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

    return instance;
}
文本組件

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

DOM標簽組件

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

,

,等.
當開發(fā)者使用React時,此時的

并不是原生的
標簽,他其實是React生成的
Virtual DOM對象,只不過標簽名稱相同罷了.

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

        if (registrationNameModules.hasOwnProperty(propKey)) {
            // 針對當前的節(jié)點添加事件代理
            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)建屬性標識
            var markup = null;
            if (this._tag != null && isCustomComponent(this._tag, props)) {
                markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
            }
            if (markup) {
                ret += " " + markup;
            }
        }
    }
    // 對于靜態(tài)頁面,不需要設(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)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84660.html

相關(guān)文章

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

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

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

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

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

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

    wean 評論0 收藏0
  • React 源碼深度解讀(九):單個元素更新

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

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

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

    sutaking 評論0 收藏0

發(fā)表評論

0條評論

kuangcaibao

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<