Render Function
渲染函数是组成完整的响应性渲染系统的另外一半,Vue的template实际上是通过渲染函数渲染出来的。
在Vue上下文中,当我们第一次渲染一个Vue应用时,会将template放到渲染函数进行编译。Render函数实际上是一个返回虚拟DOM的函数,然后Vue基于虚拟DOM生成真实DOM。
在后续的产生虚拟DOM的过程本质上是调用渲染函数,因为渲染函数和所有的data属性有依赖关系,在Vue中,这些data属性是具有响应性的,所有这些data属性会帮助这个组件的渲染函数收集依赖,如果这些依赖关系中的任何一个发生变化,将会再次调用渲染函数,它会返回一个新的虚拟DOM,新的虚拟DOM会和旧的虚拟DOM进行比较,最后,把最少量的更改应用到真实DOM中。
Render Function API
export default {
render (h) {
return h('div', {}, [...])
}
}
?render函数接收一个参数h(hyper script超文本脚本),h需要三个参数,第一个参数是元素类型,第二个参数是数据对象(可选),第三个参数是一个数组表示子节点。它会返回这个虚拟DOM树的顶层元素,以便返回整个树。
虚拟DOM(Virtual DOM)
?通常情况下,调用真实DOM的开销十分的大,因为真实DOM具有非常多的属性,并且它在底层实现也十分的复杂。所以很多时候我们会说直接修改DOM是比较缓慢的。虚拟DOM的结构十分简单,因此它的开销会比真实DOM小很多
Virtual DOM
//tag标签名;data数据对象,如果没有数据对象可以忽略
//children可以拥有子虚拟节点,这样就构成了一个虚拟DOM树
{ tag: 'div', data:{ attrs:{}, ...}, children:[] }
虚拟DOM的本质是用轻量的Javascript数据格式来表示真实DOM在特定时间的外在表现,我们每次更新信息,先构造一个新的虚拟DOM,我们先计算差异,然后将这些更改应用到DOM上。
响应性和Render Function整合
?每一个组件都有一个渲染函数,它实际上包装在我们之前实现的autorun函数(笔记1)中,当数据发生变化的时候,观察者(wathcer)通过调用data属性中的getter收集依赖项,并监听setter,将收集到的改变通知到渲染函数,渲染函数再生成一个新的虚拟DOM。只要我们依赖的渲染属性发生变化,就会不断循环上述步骤。
每个组件都有自己的自动循环渲染,组件树有许多组件构成,每个组件都只负责自己的依赖。
由于你可以更改数据依赖关系,你的数据可以再任何地方发生改变,但是因为么个组件都只负责自己的依赖,再整个组件树中我们确切的知道哪些组件受到哪些数据的影响,所以,它有一个精确的依赖跟踪系统,不会造成过多的组件发生不必要的重新渲染。
相比于React自上而下的渲染模型,Vue可以说省去了一部分优化的工作。但是也付出了一部分将数据转换为getter和setter的开销。因此有了React上限高(优化做得好的话),下限低(优化不好),而Vue下限高(一部分优化工作自动完成),上限低(相比React开销更大一些)。但是在实际应用中,两者的差距其实很小,只有在极端情况下才会出现较大偏差。
一个简单的组件
<div id="app">
<example :tags="['h1', 'h2', 'h3']"></example>
</div>
//定义一个新的Vue组件,组件就是自定义元素,
//第一个参数为组件名,第二个参数为可选的函数部分,第三个参数为template写组件内容
Vue.component('example', {
//表示组件是纯函数式组件,只根据props计算渲染输出,本身不包含不改变仍和state
functional: true,
props: {
tags: {
type: Array,
//自定义验证函数
validator (arr) {return !!arr.length }
}
},
//渲染函数
render: (h, context) => {
const tags = context.props.tags
//hyper script,接受第一个参数为tagname标签名
//第二个参数为数据对象(可选),第三个参数为子节点
return h('div', context.data, tags.map((tag, index) => h(tag, index)))
}
})
new Vue({ el: '#app' })
?参考视频:尤雨溪教你写vue 高级vue教程 源码分析 中文字幕翻译完毕_哔哩哔哩_bilibili
参考github:GitHub - zhengguorong/vue-advanced-workshop: Vue.js workshop hosted by Evan You through Frontend Masters
|