compile 這個方法是正真開始構建虛擬dom,這裏值得注意的地方是,虛擬dom和真實dom的差異,說到這裏相信許多同窗跟我同樣有不少疑惑,既然已經有虛擬dom了爲何還要構建真實dom,咱們操做了虛擬dom之後直接appendChild不行嘛。答案是no, 虛擬dom並非dom,他只是描述了一個dom結構,編譯模版的過程(模版有兩種來源,這裏不述),就是根據模版的html結構來建立虛擬dom的過程,若是你們沒沒懂,那麼請看如下代碼:
* 模版結構> <ul class=」list」> > <li>item 1</li> > <li>item 2</li> > </ul>
* 根據模版結構生成的虛擬dom結構,javascript
>{ type: ‘ul’, props: { ‘class’: ‘list’ }, children: [ > { type: ‘li’, props: {}, children: [‘item 1’] }, > { type: ‘li’, props: {}, children: [‘item 2’] } >] }
以上代碼時不是清晰明瞭,虛擬dom只是描述了一種數據結構,他並不表明真實的dom對象,他只是描述了一個dom tree該有的組織方式,編譯的過程就是根據模版結構生成dom數據結構的方式,高大上一點叫作虛擬dom。
Sumarry一下:
- Virtual DOM is any kind of representation of a real DOM (虛擬dom只是真實dom的一個表明)
- When we change something in our Virtual DOM Tree, we get a new Virtual Tree. Algorithm compares these two trees (old and new), finds differences and makes only necessary small changes to real DOM so it reflects virtual (若是咱們在虛擬dom中對數據作了修改,咱們會獲得一個新的虛擬dom結構,算法比較這兩顆dom樹,找到不一樣之處,只須要在真實dom中作必要的修改來對應虛擬DOM)在編譯期間咱們要作的就是根據模版DOM結構來構造一個數據結構來對應模版html結構
mounted 見名知意,掛載,表示真實dom已經夠早完畢,咱們能夠append到父容器當中來構造頁面了,在這裏咱們就能夠完成一些對於真實dom的操做,不管是直接訪問dom的屬性內容或者事件的綁定,均可以在這裏放心大膽的作了,通常狀況下咱們不須要直接操做dom,Vue也不推薦這麼作,可是這裏你須要知道的事若是你有這種需求,徹底能夠在這裏完成,掛載的過程就是將生成的真實DOM對象append到掛載點下面,就是appendChild的過程,這個時候的虛擬dom結構根生成出來的real dom結構如出一轍,咱們之後要操做的就是這個虛擬dom結構,就是前面根據模版生成出來的dom數據結構。css
beforeUpdate這個方法在整個生命週期之中也只被調用一次,在作什麼呢,想想上面所作的事情,上面是根據模版構造出來一個真實的dom對象,到如今他並無跟咱們的vue實例對象扯上關係,怎麼經過咱們的vue實例來影響到真實的dom對象呢,怎麼把咱們的數據綁定的真實dom當中了,之後咱們只須要操做數據就能夠影響到dom結構的渲染呢?在這個方法裏,Vue一樣依據前面的規則根據vue實例提供的數據在模版中的位置來從新生成一個虛擬dom數據結構,沒錯,你沒看錯,咱們要生成兩個虛擬dom,前一個dom只是dom結構,並無綁定咱們vue的屬性數據,這一個dom是綁定了咱們vue實例數據的dom結構,在這個dom生成的過程當中,vue根據本身的語法規則,對好比指令,表達式之類的東西進行替換,生成一個新的虛擬dom結構,接下來咱們要作什麼,我想你們應該所料不錯,沒錯,鼻孔朝天的那位同窗說的很對,就是進行比較兩個虛擬dom之間存在的差別。請不要走開,廣告以後更加精彩。。。。。html
update,接着上一集,咱們繼續吹,這個方法在咱們整個生命週期以內會反覆調用,你會發現,每一次對vue對象的變動都會觸發update方法,他作了什麼呢,他就是在反覆的生成一個virtual dom,生成的新dom不斷跟以前的dom結構進行比對,這裏又一個比較高大上的比對算法,叫differ,我想在座各位同窗是否是有一種恍然大悟的趕腳,前面幾集我說過,Vue在beforeMount的時候會對每個dom節點進行標記,他爲了什麼嘞? 你懂了沒有呢?不懂去面壁,Vue對每個節點進行標記就是爲了更加快速準確的定位dom節點。。。vue
用一種更加清楚明瞭的總結方式就是代碼:java
// 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實例對象生成的一個逆過程,一句話來講就是:潮水怎麼來就怎麼退去。。ajax