關(guān)于一些Vue的文章。(5)

原文鏈接我的blog,歡迎STAR。

前三篇里,我們開始從render, template, el的渲染DOM樹的優(yōu)先級,最終都編譯成render函數(shù),而后得到vnode(虛擬DOM),經(jīng)過diff算法后,得到真實DOM。

那么問題來了?得到真實DOM以后接下來該做什么?以及怎么做?

照例,分享一篇文章,vue。(官網(wǎng),暫時還沒有找到一篇文章能比較好的解決上述幾個問題,so,我們帶著問題出發(fā),直接上官網(wǎng),然后上源碼。)


我們先解決第一個問題,得到真實DOM以后,接下來該做什么?

相信各位同學(xué)對原生的創(chuàng)建元素節(jié)點對象,一定不陌生:

const odiv = document.createElement('div'), 此時雖然已經(jīng)新創(chuàng)建一個元素節(jié)點,但它還不是任何一顆DOM節(jié)點樹的組成部分,它只是游蕩在JavaScript世界里的一個孤兒。這種情況稱文檔碎片(document fragment),不過它已經(jīng)有了DOM屬性。接下來,我們需要把新創(chuàng)建的元素節(jié)點插入DOM節(jié)點樹,parent.appendChild(odiv)。

由此,我們猜想,是不是也要像上述中parent.appendChild(odiv)一樣,插入到DOM節(jié)點樹上?

官網(wǎng)里,有一個重要的信息:

beforeMount hook
beforeMount hook

是的,在Vue里,也需要插入到DOM節(jié)點樹上,并且有一個名字掛載。

于是,第一個問題解決,真實DOM之后,掛載到DOM節(jié)點樹上。


現(xiàn)在來解決第二個問題,該怎么掛載到DOM節(jié)點樹上?

存在兩種種方式(一般是在main.js文件中可以看到):

  • 第一種不存在el選項。


    不存在el選項,需要使用vm.$mount(),手動地掛載一個未掛載的實例
    不存在el選項,需要使用vm.$mount(),手動地掛載一個未掛載的實例
  • 第二種存在el選項。


    存在el選項時
    存在el選項時

這有兩個值得注意的地方:

  • 細(xì)心的同學(xué),應(yīng)該已經(jīng)發(fā)現(xiàn)上面兩種方法并不只是是否存在el選項的差別,在第一個方法里,使用的是render: h => h(App), 而第二種使用的是...App。

    • 關(guān)于第一種寫法render: h => h(App),h實際是createElement的別名,也是一個通用慣例。至于=>這個是es6里面的箭頭函數(shù)寫法,所以換一種寫法也就是(不涉及this):
        render: function (createElement) {
            return createElement(App)
        }
    

    App組件最終也會編譯成render函數(shù),從而有vnode。

    貼一張官網(wǎng)的圖:

    createElement參數(shù)
    createElement參數(shù)

    或者使用jsx時這樣更容易:
    jsx語法
    jsx語法

    • 第二種寫法...App,這個其實也比較容易理解,...是es6擴展運算符,關(guān)于擴展運算符不做深入,具體的學(xué)習(xí),可以參照阮老師寫的教程。在這里...App的意思是:取出App實例對象的所有可枚舉屬性,混入全局配置。

    或許你還有點疑問,這里既沒有render又沒有template,如果用掛載DOM元素的HTML用作模板,那必須使用獨立構(gòu)建的Vue庫。怎么編譯的?別急,我們來看App實例對象里有些什么可枚舉屬性:

    打印出一個新對象,對象的屬性包含App對象中可枚舉的屬性
    打印出一個新對象,對象的屬性包含App對象中可枚舉的屬性

    得到結(jié)果
    得到結(jié)果

    其中有個render方法,于是render混入到了new Vue({})的配置中。

  • 另一個值得注意的地方是:

也就是說,如果el選項在實例化時,沒有作用,且沒有顯示調(diào)用vm.$mount()手動開啟編譯時,是不會編譯成render函數(shù)的,從而不會存在vnode。

編譯成render函數(shù),有真實DOM以后,插入通過el選項,或者顯示調(diào)用vm.$mount()手動設(shè)置一個掛載點,掛載到DOM上。

第二個問題解決。


下一篇,我們深入源碼,看看這個elvm.$mount()在搞什么事。

完。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容