//要求是經過size的值來動態生成title-size標籤的組件
< title-size :size="1">Hello world!< /title-size>
複製代碼
此時採用以前的常規作法,咱們會選擇javascript
< script type="text/x-template" id="titleSize-template">
< h1 v-if="size === 1">
< slot>< /slot>
< /h1>
< h2 v-else-if="size === 2">
< slot>< /slot>
< /h2>
< h3 v-else-if="size === 3">
< slot>< /slot>
< /h3>
< h4 v-else-if="size === 4">
< slot>< /slot>
< /h4>
< h5 v-else-if="size === 5">
< slot>
< /h5>
< h6 v-else-if="size === 6">
< slot>
< /h6>
< /script>
複製代碼
Vue.component('anchored-heading', {
template: '#titleSize-template',
props: {
size: {
type: Number,
required: true
}
}
})
複製代碼
此時的組件根據prop取到的數據size值進行選擇標籤的類型,從而完成動態生成title-size標籤的組件。可是這樣的話是咱們在template中定義不一樣的h1~h6的標籤,而後再去根絕size的值來決定取得是哪一個標籤,這樣的話在數據的處理上顯得被動不靈活。而且用這種方式處理時,須要重複使用< slot>< /slot>來插入title-size的內容,反正總結起來就是低效。html
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.size, // tag name 標籤名稱
this.$slots.default // 子組件中的陣列
)
},
props: {
size: {
type: Number,
required: true
}
}
})
複製代碼
註釋: this.$slots.default對用 template的的使用沒有name(做用至關於以上例子中的slot標籤)vue
深刻渲染函數以前,咱們須要瞭解一些瀏覽器的工做原理,當瀏覽器讀html代碼時,它會創建一個「DOM 節點」樹來保持追蹤。每一個元素都是一個節點。每片文字也是一個節點。甚至註釋也都是節點。一個節點就是頁面的一個部分。就像家譜樹同樣,每一個節點均可以有孩子節點 (也就是說每一個部分能夠包含其它的一些部分)。js的運行速度是很快的,可是dom的渲染確實很慢的,每每是影響性能的一個重要因素。java
< h1>{{ testData }}< /h1>
複製代碼
render: function (createElement) {
return createElement('h1', this.testData)
}
複製代碼
當數據發生改變時,頁面的dom都會被及時高效的去渲染,而不須要本身去作其餘的處理。express
Vue 經過創建一個虛擬 DOM 對真實 DOM 發生的變化保持追蹤。能夠作個例子:編程
return createElement('h1', this.testData)
複製代碼
createElement 返回的是什麼呢?其實不是一個實際的 DOM 元素。它更準確的名字多是 createNodeDescription,由於它所包含的信息會告訴 Vue 頁面上須要渲染什麼樣的節點,及其子節點。咱們把這樣的節點描述爲「虛擬節點 (Virtual Node)」,也常簡寫它爲「VNode」。「虛擬 DOM」是咱們對由 Vue 組件樹創建起來的整個 VNode 樹的稱呼。瀏覽器
// @returns {VNode} 返回的是一個描述對象它所包含的信息會告訴 Vue 頁面上須要渲染什麼樣的節點
createElement(
// {String | Object | Function}
// 一個 HTML 標籤字符串,組件選項對象,或者
// 解析上述任何一種的一個 async 異步函數,必要參數。
'div',
// {Object}
// 一個包含模板相關屬性的數據對象
// 這樣,能夠在 template 中使用這些屬性。可選參數。
{
},
// {String | Array}
// 子節點 (VNodes),由 `createElement()` 構建而成,
// 或使用字符串來生成「文本節點」。可選參數。
[
'先寫一些文字',
createElement('h1', '一條數據'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
複製代碼
在使用data時要注意:在模板語法中,v-bind:class 和 v-bind:style ,會被特別對待同樣,在 VNode 數據對象中,下列屬性名是級別最高的字段。該對象也容許你綁定普通的 HTML 特性,就像 DOM 屬性同樣,好比 innerHTML (這會取代 v-html 指令)。(此處的官方文檔寫的很全了,就直接拿過來了)markdown
{
// 和`v-bind:class`同樣的 API
'class': {
foo: true,
bar: false
},
// 和`v-bind:style`同樣的 API
style: {
color: 'red',
fontSize: '14px'
},
// 正常的 HTML 特性
attrs: {
id: 'foo'
},
// 組件 props
props: {
myProp: 'bar'
},
// DOM 屬性
domProps: {
innerHTML: 'baz'
},
// 事件監聽器基於 `on`
// 因此再也不支持如 `v-on:keyup.enter` 修飾器
// 須要手動匹配 keyCode。
on: {
click: this.clickHandler
},
// 僅對於組件,用於監聽原生事件,而不是組件內部使用
// `vm.$emit` 觸發的事件。
nativeOn: {
click: this.nativeClickHandler
},
// 自定義指令。注意,你沒法對 `binding` 中的 `oldValue`
// 賦值,由於 Vue 已經自動爲你進行了同步。
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// Scoped slots in the form of
// { name: props => VNode | Array }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 若是組件是其餘組件的子組件,需爲插槽指定名稱
slot: 'name-of-slot',
// 其餘特殊頂層屬性
key: 'myKey',
ref: 'myRef'
}
複製代碼