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)
]
等等
总结
写组件的方式
- template
- render function
- jsx