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

資訊專欄INFORMATION COLUMN

【Vue原理】從模板到DOM的簡要流程

wenzi / 2944人閱讀

摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理從模板到的簡要流程今天的計(jì)劃是,

寫文章不容易,點(diǎn)個(gè)贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 Vue版本 【2.5.17】

如果你覺得排版難看,請點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧

【Vue原理】從模板到DOM的簡要流程

今天的計(jì)劃是,探索Vue模板掛載到頁面是怎么樣的一個(gè)流程,內(nèi)容是指 正常 HTML 標(biāo)簽的模板掛載,這部分內(nèi)容很重要。

而這部分內(nèi)容也是為了 講解 Component 作為鋪墊,因?yàn)榈阶詈?Component 必然也是作為一個(gè)正常標(biāo)簽去掛載,所以先把這部分抽出來講

首先,這個(gè)流程,個(gè)人認(rèn)為可以分為兩大部分,分別是 init 和 mount

顧名思義,init 必定是和初始化有關(guān),mount 和 掛載DOM 有關(guān)

Init

首先,當(dāng)你開始調(diào)用 Vue 的時(shí)候,比如這樣

// js

new Vue({    

    el: document.getElementsByTagName("div")[0],

})


// html,夠簡潔了吧

那么,先進(jìn)入的肯定是 Vue 這個(gè)構(gòu)造函數(shù),呈上來!

function Vue(options) {    

    this._init(options);

}

Vue.prototype._init = function(options) {    

    // 初始化 選項(xiàng),computed,data 之類的

    // 初始化實(shí)例,給實(shí)例綁定些方法
    // 觸發(fā) beforeCreated,created 鉤子

}

這個(gè) _init 方法,是構(gòu)建Vue 實(shí)例的時(shí)候調(diào)用的,而創(chuàng)建Vue 實(shí)例,并非只有通過 new Vue 創(chuàng)建,有可能是 Vue 內(nèi)部創(chuàng)建的,比如 component

所以,才需要提取出一個(gè) init 方法

然后,init 到這里就結(jié)束了,下面就到了另一個(gè)流程 mount

Mount

init 結(jié)束,就開始解析模板啦,生成DOM 啦,掛載DOM 啦 之類的

開始正文,首先,從什么時(shí)候開始?此時(shí)需要亮出 _init 方法,沒錯(cuò),就是上面出現(xiàn)的方法

其實(shí)在這個(gè)方法的最后,有一個(gè)調(diào)用執(zhí)行掛載DOM 的方法,如下

Vue.prototype._init = function(options) {
    .....
    if (vm.$options.el) {
        vm.$mount(vm.$options.el);
    }
}

可以看到一句代碼,vm.$mount ,沒錯(cuò),就在這里開啟了 DOM 掛載的 里程碑

但是,等等,有限制條件 vm.$options.el,也就是,必須有傳入 el 才會在 最后調(diào)用 掛載DOM

所以,并不是所有的 Vue 實(shí)例新建都會在 init 結(jié)尾調(diào)用 vm.$mount 去掛載DOM,比如 component 兩個(gè)過程就是分開的

我們還是先來看看 vm.$mount 吧

Vue.prototype.$mount = function(el) {    

    return mountComponent(this, query(el))

};

var mount = Vue.prototype.$mount;

Vue.prototype.$mount = function(el) {

    ...解析模板,生成模板渲染函數(shù),保存渲染函數(shù)到 options    

    return mount.call(this, el)

}
原樣呈現(xiàn)了,Vue 中有兩個(gè) $mount 函數(shù),第一個(gè)的作用是給第二個(gè) 調(diào)用......如果大家看源碼,不要搞混了喂

其中涉及到一個(gè)函數(shù),mountComponent,速看

function mountComponent(vm, el) {    

    new Watcher(vm, function() {
        vm._update(vm._render()
    })    
    return v
}

function Watcher(vm, expOrFn) {    

    this.getter = expOrFn;    

    this.get();

}

Watcher.prototype.get = function() {
    value = this.getter(vm);
}

上面代碼的作用可以說是,為 Vue 實(shí)例新建監(jiān)聽者 watcher,并設(shè)置一個(gè)更新函數(shù)

而這個(gè)更新函數(shù),會在新建 watcher后 馬上執(zhí)行,就是馬上執(zhí)行了一遍這行代碼

vm._update(vm._render())
1、vm._render

這個(gè)函數(shù)的作用是,執(zhí)行之前解析得到的【渲染函數(shù)】,渲染函數(shù)執(zhí)行完會返回一個(gè) 模板對應(yīng)的 【VNode】

vm._render 再把這個(gè) vnode 返回

于是就把這個(gè) vnode,傳給了 vm._update 中當(dāng)做了第一個(gè)參數(shù)

render 函數(shù)的內(nèi)容其實(shí)非常的多,但是這里一筆帶過,只用知道是用來生成Vnode 就好了,具體的內(nèi)容會有具體的文章講解

Vue.prototype._render = function() {
    vnode = render();    

    return vnode
}
2、vm._update

這個(gè)函數(shù)的作用是,對比 vnode,掛載更新DOM

1、如果存在舊 vnode,那么會對比舊 vnode 和 剛傳入的新 vnode,不斷地 patch 得到最小變化單位,從而只更新這部分DOM

2、如果不存在舊 vnode,那么就直接把 vnode 轉(zhuǎn)換為 dom 掛載到頁面

其中,生成DOM 和 掛載DOM 用到的方法是 createElm

方法很簡單,無非就是通過 標(biāo)簽名創(chuàng)建DOM,然后插入到頁面中

function createElm(vnode, parentElm, refElm) {  

    var children = vnode.children;    

    var tag = vnode.tag;

    vnode.elm = document.createElement(tag);   


    // 不斷遞歸遍歷子節(jié)點(diǎn)

    createChildren(vnode, children);    

    // 插入DOM 節(jié)點(diǎn)

    insert(parentElm, vnode.elm, refElm);
}

function createChildren(vnode, children) {    

    if (Array.isArray(children)) {        

        for (var i = 0; i < children.length; ++i) {

            createElm(children[i], vnode.elm, null);
        }
    }
}

function insert(parent, elm, ref) { 

    if (parent) {   

        // 如果存在兄弟節(jié)點(diǎn),就查到兄弟前面

        if (ref) {       

            // 兄弟節(jié)點(diǎn)的父節(jié)點(diǎn)和 本節(jié)點(diǎn)父節(jié)點(diǎn)相同

            if (ref.parentNode === parent) {

                parent.insertBefore(elm, ref);
            }
        } 

        // 如果沒有兄弟節(jié)點(diǎn),就直接查到父節(jié)點(diǎn)最后
        else {
            parent.appendChild(elm);
        }
    }
}
總結(jié)

兩個(gè)過程如下

init

1、初始化選項(xiàng)

2、初始化實(shí)例

mount

1、解析模板,生成并保存渲染函數(shù)

2、新建 watcher 并立即執(zhí)行更新函數(shù) vm._update(vm._render)

3、vm._render 調(diào)用渲染函數(shù)生成 VNode,傳給 vm._update

4、調(diào)用 vm._update,根據(jù) VNode 生成 DOM 并掛載

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

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

相關(guān)文章

  • Vue原理】Component - 源碼版 之 掛載組件DOM

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理源碼版之掛載組件由這篇文章從模 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...

    lbool 評論0 收藏0
  • Vue原理】Component - 白話版

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理白話版從模板上使用到掛載到頁面 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...

    liuyix 評論0 收藏0
  • Vue原理】Event - 源碼版 之 綁定標(biāo)簽DOM事件

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理源碼版之綁定標(biāo)簽事件這里的綁定 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...

    phoenixsky 評論0 收藏0
  • Vue原理】Compile - 源碼版 之 新建實(shí)例 compile結(jié)束主要流程

    摘要:頁面這個(gè)實(shí)例,按理就需要解析兩次,但是有緩存之后就不會理清思路也就是說,其實(shí)內(nèi)核就是不過是經(jīng)過了兩波包裝的第一波包裝在中的內(nèi)部函數(shù)中內(nèi)部函數(shù)的作用是合并公共和自定義,但是相關(guān)代碼已經(jīng)省略,另一個(gè)就是執(zhí)行第二波包裝在中,目的是進(jìn)行緩存 寫文章不容易,點(diǎn)個(gè)贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 ...

    CODING 評論0 收藏0
  • Vue原理】VNode - 源碼版

    摘要:表示虛擬節(jié)點(diǎn),為什么叫虛擬節(jié)點(diǎn)呢,因?yàn)椴皇钦娴墓?jié)點(diǎn)。因?yàn)槭菍ο螅还苓€是瀏覽器,都可以統(tǒng)一操作,從而獲得了服務(wù)端渲染原生渲染手寫渲染函數(shù)等能力減少操作。 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點(diǎn)擊 下面鏈接 或者 拉到 下...

    layman 評論0 收藏0

發(fā)表評論

0條評論

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