render function
-
類型:
(createElement: () => VNode) => VNode
-
詳細:
字符串模板的代替方案,允許你發揮 JavaScript 最大的編程能力。該渲染函數接收一個
createElement
方法作爲第一個參數用來創建VNode
。如果組件是一個函數組件,渲染函數還會接收一個額外的
context
參數,爲沒有實例的函數組件提供上下文信息。Vue 選項中的
render
函數若存在,則 Vue 構造函數不會從template
選項或通過el
選項指定的掛載元素中提取出的 HTML 模板編譯渲染函數。
組件中的 template 會被編譯成 render function。
下例中,直接用 render function 代替 template,結果相同。
import Vue from 'vue'
const component = {
name: 'comp',
// template: `
// <div :style="style">
// <slot></slot>
// </div>
// `,
render (createElement) {
return createElement('div', {
style: this.style
}, this.$slots.default)
},
data () {
return {
style: {
width: '200px',
height: '200px',
border: '1px solid #aaa'
},
value: 'component value'
}
}
}
new Vue({
components: {
CompOne: component
},
el: '#root',
data () {
return {
value: '123'
}
},
mounted () {
console.log(this.$refs.comp, this.$refs.span, this.$refs.comp.value)
},
template: `
<div>
<comp-one ref="comp">
<span ref="span">{{value}}</span>
</comp-one>
</div>
`,
render (createElement) {
return createElement(
'comp-one',
{
ref: 'comp'
},
[
createElement('span', {
ref: 'span'
}, this.value)
])
}
})
複製代碼
createElement
createElement,是 vue 虛擬 DOM 的概念,創建出來的並不是 html 節點,而是 VNode 的一個類,類似 DOM 結構的一個結構,並存在內存中,它會和真正的 DOM 進行對比,若發現需要更新的 DOM,纔會去轉換這部分 DOM 內容,並填到真正的 DOM 中,從而提高性能。
createElement 可使用的屬性
指令
傳值 props
render (createElement) {
return createElement(
'comp-one',
{
ref: 'comp',
props: { // props 傳值
props1: this.value
}
},
[
createElement('span', {
ref: 'span'
}, this.value)
])
}
複製代碼
綁定事件
on
render (createElement) {
return createElement(
'comp-one',
{
ref: 'comp',
on: { // 事件監聽(一),這裏是組件上監聽,需要 $emit
click: this.handleClick
},
},
[
createElement('span', {
ref: 'span'
}, this.value)
])
}
複製代碼
nativeOn
render (createElement) {
return createElement(
'comp-one',
{
ref: 'comp',
nativeOn: {
click: this.handleClick
}
},
[
createElement('span', {
ref: 'span'
}, this.value)
])
}
複製代碼
nativeOn 與 on 的區別
nativeOn 也是綁定到組件上,但是不需要組件發 $emit
,它會自動綁定到這個組件的根節點的原生 DOM 上,如果本身就是原生 DOM,直接綁定。
slot
// 組件中
render (createElement) {
return createElement('div', {
style: this.style,
on: {
click: () => { this.$emit('click') }
}
}, [
this.$slots.header, // 通過 $slot拿到 header,如果沒命名就是 default
this.props1
])
}
// new Vue()
[
createElement('span', {
ref: 'span',
slot: 'header' // 指定具名插槽
}, this.value)
]
複製代碼
domProps
類似原生 DOM 操作,把 span 覆蓋掉了。
[
createElement('span', {
ref: 'span',
slot: 'header',
domProps: {
innerHTML: '<span>345</span>'
}
}, this.value)
]
複製代碼
attrs
給 span 加一個 id。
[
createElement('span', {
ref: 'span',
slot: 'header',
// domProps: {
// innerHTML: '<span>345</span>'
// }
attrs: {
id: 'test-id'
}
}, this.value)
]