一、生命周期

Vue生命周期是指vue實例對象從創(chuàng)建之初到銷毀的過程,掌握和理解生命周期過程中每一個步驟的作用,可以更加合理的安排我們不同業(yè)務邏輯具體的執(zhí)行位置。

beforeCreate在官方文檔描述中說,在做一些數(shù)據(jù)監(jiān)視和事件初始化,這里有一個容易讓人走偏的地方,就是事件初始化,其實就是為vue對象添加一些屬性,就是methods中的一些函數(shù)全部作為vue對象的屬性存在,Vue會講所有的data數(shù)據(jù)和methods中的函數(shù)添加到創(chuàng)建的vue對象上面。

created 這個方法表示,vue對象已經(jīng)創(chuàng)建成功,這里要搞清楚vue對象并不是我們所說的虛擬dom,vue對象就是一個js對象,他內部只是對數(shù)據(jù)進行操作,通過對數(shù)據(jù)的操作進而影響到虛擬dom的構建,所以在這個方法中我們可以做一些數(shù)據(jù)初始化工作,最常見的就是發(fā)送ajax請求來對已經(jīng)構建完畢的vue對象的靜態(tài)屬性進行一些初始化

compile 這個方法是正真開始構建虛擬dom,這里值得注意的地方是,虛擬dom和真實dom的差別,說到這里相信許多同學跟我一樣有很多疑惑,既然已經(jīng)有虛擬dom了為什么還要構建真實dom,我們操作了虛擬dom以后直接appendChild不行嘛。答案是no, 虛擬dom并不是dom,他只是描述了一個dom結構,編譯模版的過程(模版有兩種來源,這里不述),就是根據(jù)模版的html結構來創(chuàng)建虛擬dom的過程,如果大家沒沒懂,那么請看以下代碼:

* 模版結構

<ul ?class='list'><li>item1</li><li>item2</li></ul>

* 根據(jù)模版結構生成的虛擬dom結構,

{

????????type: ‘ul’, props: { ‘class’: ‘list’ },

?????????children: [ ? ?

????????????????????????????{type: ‘li’, props: {}, children: [‘item 1’] },

?????????????????????????? ?{type: ‘li’, props: {}, children: [‘item 2’] }

????????????????????????]

?}

以上代碼時不是清晰明了,虛擬dom只是描述了一種數(shù)據(jù)結構,他并不代表真實的dom對象,他只是描述了一個dom tree該有的組織方式,編譯的過程就是根據(jù)模版結構生成dom數(shù)據(jù)結構的方式,高大上一點叫做虛擬dom。Sumarry一下:- Virtual DOM is any kind of representation of a real DOM (虛擬dom只是真實dom的一個代表)- When wechangesomethinginourVirtualDOM Tree, wegetanewVirtualTree. Algorithm compares these two trees (oldandnew), finds differencesandmakesonlynecessary small changestorealDOM so it reflectsvirtual(如果我們在虛擬dom中對數(shù)據(jù)做了修改,我們會得到一個新的虛擬dom結構,算法比較這兩顆dom樹,找到不同之處,只需要在真實dom中做必要的修改來對應虛擬DOM)在編譯期間我們要做的就是根據(jù)模版DOM結構來構造一個數(shù)據(jù)結構來對應模版html結構

beforeMount 這個過程就是根據(jù)編譯以后產生的虛擬dom結構來構造一個真實的dom結構,再說一遍,這兩個dom有很大的區(qū)別,前者只表示數(shù)據(jù)結構,后者可以直接添加到html文檔結構中來渲染一個效果。在這個期間,我們就可以操作真實的dom對象了,包括我們?yōu)槟骋粋€特定的dom節(jié)點綁定事件,標簽屬性,內容的操作等,例如使用select2來修飾select,但是并不推薦在這里進行一些事件綁定或者dom操作,因為在這期間,Vue還要做一件非常重要的事情就是通過Vue自己的方式來標識每一個真實的dom節(jié)點,我們在vue里一般都是通過$els或者$refs來操作對應的dom元素,但是這期間正是標注所有元素的過程,很有可能會出一些意想不到的錯誤。

mounted 見名知意,掛載,表示真實dom已經(jīng)夠早完畢,我們可以append到父容器當中來構造頁面了,在這里我們就可以完成一些對于真實dom的操作,不論是直接訪問dom的屬性內容或者事件的綁定,都可以在這里放心大膽的做了,一般情況下我們不需要直接操作dom,Vue也不推薦這么做,但是這里你需要知道的事如果你有這種需求,完全可以在這里完成,掛載的過程就是將生成的真實DOM對象append到掛載點下面,就是appendChild的過程,這個時候的虛擬dom結構根生成出來的real dom結構一模一樣,我們以后要操作的就是這個虛擬dom結構,就是前面根據(jù)模版生成出來的dom數(shù)據(jù)結構。

beforeUpdate這個方法在整個生命周期之中也只被調用一次,在做什么呢,想一想上面所做的事情,上面是根據(jù)模版構造出來一個真實的dom對象,到現(xiàn)在他并沒有跟我們的vue實例對象扯上關系,怎么通過我們的vue實例來影響到真實的dom對象呢,怎么把我們的數(shù)據(jù)綁定的真實dom當中了,以后我們只需要操作數(shù)據(jù)就可以影響到dom結構的渲染呢?在這個方法里,Vue同樣依據(jù)前面的規(guī)則根據(jù)vue實例提供的數(shù)據(jù)在模版中的位置來重新生成一個虛擬dom數(shù)據(jù)結構,沒錯,你沒看錯,我們要生成兩個虛擬dom,前一個dom只是dom結構,并沒有綁定我們vue的屬性數(shù)據(jù),這一個dom是綁定了我們vue實例數(shù)據(jù)的dom結構,在這個dom生成的過程中,vue根據(jù)自己的語法規(guī)則,對比如指令,表達式之類的東西進行替換,生成一個新的虛擬dom結構,接下來我們要做什么,我想大家應該所料不錯,沒錯,鼻孔朝天的那位同學說的很對,就是進行比較兩個虛擬dom之間存在的差異。請不要走開,廣告之后更加精彩。。。。。

update,接著上一集,我們繼續(xù)吹,這個方法在我們整個生命周期之內會反復調用,你會發(fā)現(xiàn),每一次對vue對象的變更都會觸發(fā)update方法,他做了什么呢,他就是在反復的生成一個virtual dom,生成的新dom不斷跟之前的dom結構進行比對,這里又一個比較高大上的比對算法,叫differ,我想在座各位同學是不是有一種恍然大悟的趕腳,前面幾集我說過,Vue在beforeMount的時候會對每一個dom節(jié)點進行標記,他為了什么嘞? 你懂了沒有呢?不懂去面壁,Vue對每一個節(jié)點進行標記就是為了更加快速準確的定位dom節(jié)點。。。

用一種更加清楚明了的總結方式就是代碼:

// 1. 構建虛擬DOM

????????var tree = el('div', {'id':'container'}, [? ? el('h1', {style:'color: blue'}, ['simple virtal dom']),? ? el('p', ['Hello, virtual-dom']),? ? el('ul', [el('li')])])

// 2. 通過虛擬DOM構建真正的DOM

????var root = tree.render()document.body.appendChild(root)

// 3. 生成新的虛擬DOM

? ? var newTree = el('div', {'id':'container'},?

????????????[? ??

????????????el('h1', {style:'color: red'}, ['simple virtal dom']),??

? ? ? ? ? ? el('p', ['Hello, virtual-dom']),? ??

????????????el('ul', [el('li'), el('li')])

????????????]

????????????)

// 4. 比較兩棵虛擬DOM樹的不同

var ? patches = diff(tree, newTree)

// 5. 在真正的DOM元素上應用變更

patch(root, patches)

至于之后的所有方法我想就不必深究了,他其實就是vue實例對象生成的一個逆過程,一句話來說就是:潮水怎么來就怎么退去。。

接著來聊一下性能問題。很多同學可能在想既然他存在dom操作,肯定性能會受到影響,但是這跟坊間傳言優(yōu)點不符啊,坊間都說虛擬dom性能高渲染快,但是為什么存在大量dom操作呢?接下來呢我就要跟你聊一聊瀏覽器的大致組成和你通過原聲js做這些適時數(shù)據(jù)綁定所要做的一些事情了。咸鹽少許。。。

這里引用一位老兄在知乎上的回答,我感覺說的很對也很明了,虛擬dom為什么很快:

JavaScript執(zhí)行速度很快

Dom操作很慢

Chrome剛出來的時候,在Chrome里跑Javascript非??欤o了其它瀏覽器很大壓力。而現(xiàn)在經(jīng)過幾輪你追我趕,各主流瀏覽器的Javascript執(zhí)行速度都很快了。但是遺憾的是瀏覽器廠商只對Javascript引擎進行也極限優(yōu)化,但是對html文檔結構的構建速度和css樣式的渲染并沒有多少進步,就是說dom引擎和css引擎的發(fā)展速度遠遠更不上js引擎解析js腳本的速度,這就比較尷尬了,因為js很多時候都是為了操作dom節(jié)點和修飾dom,由于html文檔結構重新排布的速度遠遠沒有js執(zhí)行速度快,這在很多時候就造成了難以理解的邏輯錯誤,稱為難以言說的痛。。。。于是在這種情況下,虛擬dom應用而生了,虛擬dom說白了就是一個js結構的對象,他內部的數(shù)據(jù)組織方式是按照html文檔結構組成的樹狀結構,我們通過每一次數(shù)據(jù)的修改來重新構造一個js對象,根據(jù)前后對象之間的比對就可以發(fā)現(xiàn)具體那個節(jié)點發(fā)生了變化,然后在真實的dom結構中迅速的定位到元素,進行修改,最小化真實dom的重排和重繪。如果你通過原聲js,每次修改dom結構或者內容,你必須從頭到尾進行dom節(jié)點遍歷,造成很大的時間和資源的浪費,這是一點,還有一點就是每一次dom操作導致的結構重新排布,所以最好的dom操作方式是一次性把要修改的東西全部做完,進行一次性行更新。而虛擬dom做到了這一點,盡量少操作dom,盡量最小化dom操作,盡量一次性操作dom,盡量不去查詢dom。

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容