Vue3-05 渲染函数
Vue3学习笔记-05 渲染函数
为什么需要渲染函数
Vue推荐多数情况使用模板创建HTML,但是在一些情况下使用渲染函数会更加方便,例如,例如要生成带有锚点的标题
1 | <h1> |
将这段代码封装为组件,传入level
作为参数,level
取值1 - 6
,对应H1 - H6
,如果使用模板需要借助slot
并且配合大量的if...else
:
1 | <template> |
模板很啰嗦,可以考虑使用渲染函数来进行优化
1 | <script lang="ts"> |
代码简洁了许多,但是要深入使用渲染函数前,需要连接实例的Property,才能将模板中的指令和参数在渲染函数中找到
实例Property API
$data
:组件实例正在监听的数据对象,等于选项API中的data
$props
:组件接收到的props
对象,等于选项API的props
$el
:组件实例正在使用的根DOM元素,建议使用ref
模板引用来直接访问DOM元素,而不是依赖于$el
$options
:组件实例的初始化选项,当在选项中定义了自定义属性时,可以使用$options
来访问$parent
:组件实例的父实例$root
:组件实例的根组件实例,如果当前实例没有父实例,返回组件自己$slots
:返回通过插槽分发的内容,$slots.default()
返回模板插槽的内容,具名slot
都会在对应的$slots
下找到,注意这是一个函数,需要()
调用后返回结果$refs
:返回组件注册过ref
属性的DOM元素和组件实例(与组合式API的ref
没有关系)$attrs
:返回了父作用域中不作为组件props
或自定义事件的attribute
绑定和事件
h
函数
h
函数用来创建虚拟Dom,它会返回一个VNode,它接受三个参数:h(tag, props, children)
tag
:必须,可以是HTML标签,也可以是异组件、异步组件或者null
(返回null
会渲染注释)props
:可选的,与attribute
、props
和事件对应的对象,会在模板(组件或HTML标签)中使用children
:可选的,可以是通过h
创建的子VNode,也可以是字符串,或者是插槽对象
1 | h('div', {}, ['Hello', h('h1', 'Title']); |
约束
VNodes必须唯一
组件数的所有的VNodes必须唯一,所以下面的渲染函数是不合法的:
1 | render() { |
官网文档中说明上面的渲染函数是非法的,但是实际上我尝试后发现,控制台并没有报错,而且渲染也是成功了。但是使用文档建议的工厂函数,也是可行的(2021-05-06)
改为使用工厂函数:
1 | render() { |
使用JavaScript代替模板功能
v-for
和v-if
v-if
是ioyngif...else
代替,v-for
使用map
代替
v-model
组件的v-model
需要在h
的第二个参数中,传入modelValue
属性和update:modelValue
方法作为VNode的Prop:
1 | props: ['modelValue'], |
v-on
我们需要为模板的事件处理程序提供正确的Prop名称,例如@click
的Prop名为onClick
,@input
的Prop名为onInput
1 | render() { |
事件修饰符
对于.passive
、.capture
、.once
事件修饰符,使用的时候需要已驼峰的形式,将它们凭借在事件名后面:
1 | render() { |
对于其他修饰符,需要在事件处理函数中自行实现(因为其他修饰符实际上就是语法糖)
插槽
使用this.$slots
来访问静态插槽内容,每个插槽都是一个VNode数组
1 | render() { |
slots
中对应的插槽名被调用时,可以传入一个对象作为传入,来实现作用域插槽的功能:
使用模板时:
1 | <!-- todo-list --> |
使用渲染函数时:
1 | render() { |
JSX
为了简化h
函数的使用,可以使用jsx-next这个Babel插件,用于在Vue使用JSX语法
1 | import AnchoredHeading from './AnchoredHeading.vue' |
什么时候使用JSX
在动态性强的场景下,JSX 会有一定优势。