一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
前言
用vue开发项目,我们平时用的模板(template)比较多,因为我们还是在template上面写html代码,可读性相对渲染函数(render)好一些。
但是render相对template来说渲染快一点,因为template需要先转成render函数。而且有些组件库的源码就是用render函数写的,我之前的写的从el-table的slot自定义内容里学到的,el-table就用到render函数和this.$scopedSlots。
所以我们今天来学习vue的渲染函数,这样下次如果需要使用也能快速使用。
渲染函数
在vue中使用渲染函数,是通过render函数,一般是接受一个参数createElement(函数组件除外),这个createElement,也是函数,返回虚拟dom,一般简写h。
{
render (h) {
return h('div', 'hello world!')
}
}
// 最后渲染出来就是<div>hello world!</div>
它接受三个参数。
-
第一个参数, 必填
类型: string / object / function
- 如果是
string,则参数是标签名,比如是div,h1,span等标签。 - 如果是
object,则参数是组件选项对象。比如h(componentName),componentName为引入的组件。 - 如果是funciton,则参数是async异步函数,然后resolve的是上面2种值其中的一种。
- 如果是
-
第二个参数,选填
类型: object
虚拟dom的数据对象,会传给当前的虚拟dom。
数据对象支持传以下属性
-
class
类名,支持对象,字符串,或者对象组成的数组
-
style
样式 支持对象,字符串,或者对象组成的数组
-
attrs
标签的属性 最终赋值到标签身上,对象类型
-
domProps
dom的属性,对象类型
-
props
传给组件的props,对象类型
-
on
事件监听,对象类型,不支持简写修饰符,比如
.stop,.prevent等 -
nativeOn
需要写在组件上,监听原生事件,比如
input,click等,vue的自定义事件不会触发。对象类型 -
directives
vue的指令,数组类型
-
scopedSlots
vue的作用域插槽,对象类型,键值可以是虚拟dom,或者虚拟dom组成的数组。
-
slot
vue的插槽,字符串类型
-
key
vue的key属性,字符串类型
-
ref
跟
template的ref一样,可以快速访问dom或者vue实例,字符串类型。
用数据对象写个例子:
{ class: { 'box': true, // 类名加上box 'container': false // 类名不会container }, style: { color: 'red' }, attrs: { name: '答案cp3' }, domProps: { innerHTML: '答案cp3' }, props: { id: 'a' }, on: { click: () => { console.log(this) } }, nativeOn: { click: () => { console.log(this) } }, scopedSlots: { a: (props) => h('div', 'hi') }, slots: 'slotName', key: 'a', ref: 'refDom' }第三个参数,选填
类型:String / Array
子节点的虚拟dom,可以是字符串,代表子节点的内容,或者虚拟dom组成的数组。
-
例子
普通元素:
render (h) {
return h('div', {
class: {
box: true
},
style: {
color: 'red'
},
attrs: {
name: '答案cp3'
},
on: {
click: () => {
console.log(this)
}
},
key: 'a',
}, 'hello world!')
}
渲染结果:
渲染自定义组件:
// child.vue
<template>
<div>
<slot></slot>
<slot name="a"></slot>
</div>
</template>
import child from './child.vue'
render (h) {
return h(child, {
scopedSlots: {
a: (props) => h('h1', '答案cp3')
},
}, 'hello world!')
}