3.2 作業(yè)

一、簡(jiǎn)答題
1、請(qǐng)簡(jiǎn)述 Vue 首次渲染的過(guò)程。

  1. 首先進(jìn)行Vue的初始化,初始化Vue的實(shí)例成員以及靜態(tài)成員。
  2. 當(dāng)初始化結(jié)束之后,開(kāi)始調(diào)用構(gòu)造函數(shù),在構(gòu)造函數(shù)中調(diào)用this._init(),這個(gè)方法相當(dāng)于我們整個(gè)Vue的入口。
  3. 在_init()中調(diào)用this.mount(),共有兩個(gè)this.mount()。

第一個(gè)this.mount()是entry-runtime-with-compiler.js入口文件,這個(gè)mount()的核心作用是幫我們把模板編譯成render函數(shù),但它首先會(huì)判斷一下當(dāng)前是否傳入了render選項(xiàng),如果沒(méi)有傳入的話,它會(huì)去獲取我們的template選項(xiàng),如果template選項(xiàng)也沒(méi)有的話,他會(huì)把el中的內(nèi)容作為我們的模板,然后把模板編譯成render函數(shù),它是通過(guò)compileToFunctions()函數(shù),幫我們把模板編譯成render函數(shù)的,當(dāng)把render函數(shù)編譯好之后,它會(huì)把render函數(shù)存在我們的options.render中。

  • src\platforms\web\entry-runtime-with-compiler.js
  • 如果沒(méi)有傳遞render,把模版編譯成render函數(shù)
  • compileToFunction()生成render()渲染函數(shù)
  • options.render=render

第二個(gè)this.mount()是runtime/index.js中的this.mount()方法,這個(gè)方法首先會(huì)重新獲取el,因?yàn)槿绻沁\(yùn)行時(shí)版本的話,是不會(huì)走entry-runtime-with-compiler.js這個(gè)入口中獲取el,所以如果是運(yùn)行時(shí)版本的話,我們會(huì)在runtime/index.js的$mount()中重新獲取el。

  • src\platforms\web\runtime\index.js
  • mountComponent()
  1. 接下來(lái)調(diào)用mountComponent(),mountComponent()是在src/core/instance/lifecycle.js中定義的,在mountComponent()中,首先會(huì)判斷render選項(xiàng),如果沒(méi)有render,但是傳入了模板,并且當(dāng)前是開(kāi)發(fā)環(huán)境的話會(huì)發(fā)送警告,警告運(yùn)行時(shí)版本不支持編譯器。接下來(lái)會(huì)觸發(fā)beforeMount這個(gè)生命周期中的鉤子函數(shù),也就是開(kāi)始掛載之前。
  2. 然后定義了updateComponent(),在這個(gè)方法中,定義了_render和_update,_render的作用是生成虛擬DOM,_update的作用是將虛擬DOM轉(zhuǎn)換成真實(shí)DOM,并且掛載到頁(yè)面上來(lái)。
  3. 再接下來(lái)就是創(chuàng)建Watcher對(duì)象,在創(chuàng)建Watcher時(shí),傳遞了updateComponent這個(gè)函數(shù),這個(gè)函數(shù)最終是在Watcher內(nèi)部調(diào)用的。在Watcher創(chuàng)建完之后還調(diào)用了get方法,在get方法中,會(huì)調(diào)用updateComponent()。
  4. 然后觸發(fā)了生命周期的鉤子函數(shù)mounted,掛載結(jié)束,最終返回Vue實(shí)例。

2、請(qǐng)簡(jiǎn)述 Vue 響應(yīng)式原理。

Vue 的響應(yīng)式原理是核心是通過(guò) ES5 的保護(hù)對(duì)象的 Object.defindeProperty 中的訪問(wèn)器屬性中的 get 和 set 方法,data 中聲明的屬性都被添加了訪問(wèn)器屬性,當(dāng)讀取 data 中的數(shù)據(jù)時(shí)自動(dòng)調(diào)用 get 方法,當(dāng)修改 data 中的數(shù)據(jù)時(shí),自動(dòng)調(diào)用 set 方法,檢測(cè)到數(shù)據(jù)的變化,會(huì)通知觀察者 Wacher,觀察者 Wacher自動(dòng)觸發(fā)重新render 當(dāng)前組件(子組件不會(huì)重新渲染),生成新的虛擬 DOM 樹(shù),Vue 框架會(huì)遍歷并對(duì)比新虛擬 DOM 樹(shù)和舊虛擬 DOM 樹(shù)中每個(gè)節(jié)點(diǎn)的差別,并記錄下來(lái),最后,加載操作,將所有記錄的不同點(diǎn),局部修改到真實(shí) DOM 樹(shù)上。

3、請(qǐng)簡(jiǎn)述虛擬 DOM 中 Key 的作用和好處。

在v-for的過(guò)程中,為給每一個(gè)節(jié)點(diǎn)設(shè)置key屬性的作用:

  1. 以便它能夠跟蹤每個(gè)節(jié)點(diǎn)的身份,在進(jìn)行比較的時(shí)候,會(huì)基于 key 的變化重新排列元素順序。從而重用和重新排序現(xiàn)有元素,并且會(huì)移除 key 不存在的元素。方便讓 vnode 在 diff 的過(guò)程中找到對(duì)應(yīng)的節(jié)點(diǎn),然后成功復(fù)用。

設(shè)置key的好處:

  1. 可以減少 dom 的操作,減少 diff 和渲染所需要的時(shí)間,提升了性能

4、請(qǐng)簡(jiǎn)述 Vue 中模板編譯的過(guò)程。

  1. 緩存公共的 mount 函數(shù),并重寫瀏覽器平臺(tái)的 mount
  2. 判斷是否傳入了 render 函數(shù),沒(méi)有的話,是否傳入了 template ,沒(méi)有的話,則獲取 el 節(jié)點(diǎn)的 outerHTML 作為 template
  3. 調(diào)用 baseCompile 函數(shù)
  4. 解析器(parse) 將模板字符串的模板編譯轉(zhuǎn)換成 AST 抽象語(yǔ)法樹(shù)
  5. 優(yōu)化器(optimize) - 對(duì) AST 進(jìn)行靜態(tài)節(jié)點(diǎn)標(biāo)記,主要用來(lái)做虛擬DOM的渲染優(yōu)化
  6. 通過(guò) generate 將 AST 抽象語(yǔ)法樹(shù)轉(zhuǎn)換為 render 函數(shù)的 js 字符串
  7. 將 render 函數(shù) 通過(guò) createFunction 函數(shù) 轉(zhuǎn)換為 一個(gè)可以執(zhí)行的函數(shù)
  8. 將 最后的 render 函數(shù) 掛載到 option 中
  9. 執(zhí)行 公共的 mount 函數(shù)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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