Vue2與Vue1最大的區別就在於Vue2使用了虛擬DOM來更新DOM節點,提高渲染性能。html
React和Vue2都使用了虛擬DOM技術,虛擬DOM並非真正意義上的DOM,而是一個輕量級的JavaScript對象,在狀態發生變化時,虛擬DOM會進行Different運算,來更新只須要被替換的DOM,而不是所有重繪。數組
與DOM操做相比,虛擬DOM是基於JavaScript計算的,因此開銷會小不少。async
在Vue2中,虛擬DOM就是經過一種VNode類表達,每一個DOM元素或組件對對應一個VNode對象。函數
VNodeData
節點解析:性能
children
子節點,數組,也是VNode類型。text
當前節點的文本,通常文本節點或註釋節點會有該屬性。elm
當前虛擬節點對應的真實的DOM節點。ns
節點的namespace
content
編譯做用域functionalContext
函數化組件的做用域key
節點的key
屬性,用於做爲節點的標識,有利於patch
的優化componentOptions
建立組件實例時會用到的選項信息。child
當前節點對應的組件實例。parent
組件的佔位節點。raw
原始html
isStatic
靜態節點的標識isRootInset
是否做爲根節點插入,被<transition>
包裹的節點,該屬性的值爲false
。isConment
當前節點是不是註釋節點。isCloned
當前節點是否爲克隆節點。isOnce
當前節點是否有v-once
指令。VNode主要能夠分爲如下幾類:優化
TextVNode
文本節點。ElementVNode
普通元素節點。ComponentVNode
組件節點。EmptyVNode
沒有內容的註釋節點。CloneVNode
克隆節點,能夠是以上任意類型的節點,惟一的區別在於isCloned
屬性爲true
。Render函數經過createElement
參數來建立虛擬DOM,結構精簡。其中,訪問slot
的用法,使用場景集中在Render函數。this
<p data-height="265" data-theme-id="0" data-slug-hash="wXozpg" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-render函數" class="codepen">See the Pen Vue-render函數 by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>spa
createElement
用法createElement
構成了Vue虛擬DOM的模板,它有3個參數:code
createElement( //{String | Object | Function} //一個HTML標籤,組件選項,或一個函數 //必須return上面其中一個 'div', //{Object} //一個對應屬性的數據對象,可選 //能夠在template中使用 //{String | Array} //子節點(VNode),可選 [ createElement('h1','hello world'), createElement(MyComponent,{ props:{ someProp:'foo' } }), 'bar' ] );
第一個參數必選,能夠是一個HTML標籤,也能夠是一個組件或函數;第二個是可選參數,數據對象,在template
中使用。第三個是子節點,也是可選參數,用法一直。component
以前在template
中都是在組件的標籤上使用v-bind:class
、v-bind:style
、v-on:click
這樣的指令,在Render函數都將其寫在了數據對象中。
全部的組件樹中,若是VNode是組件或含有組件的slot
,nameVNode必須惟一。
在Render函數裏建立了一個cloneVNode
的工廠函數,經過遞歸將slot
全部子節點都克隆了一份,並對VNode的關鍵屬性也進行復制。
在Render函數中,再也不須要Vue內置的指令,好比v-if
、v-for
。不管要實現什麼功能,均可以使用原生JavaScript。
<p data-height="265" data-theme-id="0" data-slug-hash="eKgVgQ" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="render--v-for" class="codepen">See the Pen render--v-for by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>
map()
方法時快速改變數組結構,返回一個新數組。map
常和filter
、sort
等方法一塊兒使用,它們返回的都是新數組。
Render函數裏沒有與v-model
對應的API,須要本身來實現邏輯。
<p data-height="265" data-theme-id="0" data-slug-hash="BVpYdd" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-render-API" class="codepen">See the Pen Vue-render-API by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>
v-model
就是prop:value
和event:input
組合使用的一個語法糖,雖然在Render裏寫起來比較複雜,可是能夠自由控制,深刻到更底層。
對於事件修飾符和按鍵修飾符,基本須要本身實現:
修飾符 | 對應的句柄 |
---|---|
.stop |
event.stopPropagation() |
.prevent |
event.preventDefault() |
.self |
if(event.target!==event.currentTarget) return |
.ente 、.13 |
if(event.keyCode!==13) return 替換13位須要的keyCode |
.ctrl 、.alt 、.shift 、.meta |
if(!event.ctrlKey) return 根據須要替換ctrlKey位altKey、shiftKey或metaKey |
對於事件修飾符.capture
和.once
,Vue提供了特殊的前綴,能夠直接寫在on
的配置裏。
修飾符 | 前綴 |
---|---|
.capture |
! |
.once |
~ |
.capture.once 或.once.capture |
~! |
寫法以下:
on: { '!click': this.doThisInCapturingMode, '~keyup': this.doThisOnce, '~!mouseover': this.doThisOnceInCapturingMode }
簡單模擬聊天發送內容的場景:
<p data-height="265" data-theme-id="0" data-slug-hash="ZRLrPN" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-模擬聊天發送內容" class="codepen">See the Pen Vue-模擬聊天發送內容 by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>
在Render函數中會大量使用slot
,在沒有使用slot
時會顯示一個默認的內容,這部分須要本身實現。
this.$slots.default
等於undefined
,就說明父組件中沒有定義slot
,這是能夠自定義顯示的內容。