部分摘要 - 360圖書館 號令風云
一圖勝前言
根據(jù)自己的理解對原圖進行了標注
Vue流程
Vue運行流程:
- 模板通過編譯生成AST
- AST生成Vue的render函數(shù)(渲染函數(shù))
- 渲染函數(shù)結合數(shù)據(jù)生成Virtual DOM樹
- Diff和Patch后生成新的UI
vue初始化階段
1.Vue支持我們通過data參數(shù)傳遞一個JavaScript對象做為組件數(shù)據(jù)慕匠,
2.Vue將遍歷此對象屬性影晓,使用Object.defineProperty方法設置描述對象枪孩,
3.通過存取器函數(shù)可以追蹤該屬性的變更,
4.Vue創(chuàng)建了一層Watcher層傀缩,在組件渲染的過程中把屬性記錄為依賴,
數(shù)據(jù)更新階段
1.當依賴項的setter被調用時惫周,
2.通知Watcher重新計算餐茵,
3.從而使它關聯(lián)的組件通過render去渲染虛擬dom樹
4.通過diff的核心算法patch,將新舊虛擬dom樹,比對出差異部分辆苔,渲染到頁面中去
針對編譯器模板的差異
模板編譯的當時算灸,在Vue中,可以2種驻啤,Vue流程
1.獨立構建:
包含模板編譯器菲驴,渲染過程HTML字符串 → render函數(shù) → VNode → 真實DOM節(jié)點
2.運行時構建:(只是省去了圖1中,左側的編譯期)
不包含模板編譯器街佑,渲染過程render函數(shù) → VNode → 真實DOM節(jié)點
模板書寫方式
1.自定義render方式 【上面編譯方式2】
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement (
'h' + this.level, // tag name標簽名稱
this.$slots.default // 子組件中的陣列
)
},
props: {
level: {
type: Number,
required: true
}
}
})
2.template方式【上面編譯方式1】
let app = new Vue({
template: `<div>{{ msg }}</div>`,
data () {
return {
msg: ''
}
}
})
3.el方式【上面編譯方式1】
let app = new Vue({
el: '#app',
data () {
return {
msg: 'Hello Vue!'
}
}
})
不論哪一種方式谢翎,最終都要得到render函數(shù)
渲染過程
render渲染簡化流程
原理再圖解
new Vue,執(zhí)行初始化
掛載$mount方法沐旨,通過自定義render方法森逮、template、el等生成render函數(shù)
通過Watcher監(jiān)聽數(shù)據(jù)的變化
當數(shù)據(jù)發(fā)生變化時磁携,render函數(shù)執(zhí)行生成VNode對象
通過patch方法褒侧,對比新舊VNode對象,通過DOM Diff算法谊迄,添加闷供、修改、刪除真正的DOM元素