携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情
为了后续能够更好的理解渲染器,我们需要了解一下渲染器的基本概念,顺带纠错一下,渲染器的英文是Renderer,渲染这个动词才是Render,但是如果作为函数名,我还是觉得动词比较好。
- 明确渲染器的作用。
它的作用就是把虚拟DOM渲染为某个平台的真实元素。当然在Web平台下,我们是DOM元素。
- 虚拟DOM 每个Vuer都听说过虚拟DOM,也应该知道Vue中也用了虚拟DOM,但什么才是虚拟DOM呢?虚拟DOM其实就是一个类似于DOM的树形结构,我们一般简写为vdom,其中的每一个节点又叫做虚拟节点,vnode。其实,这个解构你是可以自己定义的,比如vue2和vue3就有点差别
//vue2中的vdom
const vdom = {
tag:'p',
on:{
clicl(){}
},
children:[]
}
//vue3中的vdom
const vdom2 = {
tag:'p',
onClick(){},
children:[]
}
我们可以随便设计虚拟dom,只要你能把它渲染出来。
- 挂载
说挂载可能你不认识,但是如果说英语mount你就懂了,所谓挂载就是把虚拟dom变为真实dom的过程,在vue中有一个最重要的生命周期就是mounted,意思是已经挂载,这时候你就可以访问真实dom了,我们也会在这里初始化一些依赖dom的三方库
- 容器
容器指的是你要把虚拟dom挂载的地方,位置。我们一般会指定一个dom节点,比如#app。
在vue中,我们首先定义了一个工厂函数,然后导出一个render.之所以采用工厂模式,1是我们导出的不仅仅是web端的render,我们还可能有node端下的ssr,甚至于各种跨端工具。
const createRenderer = ()=>{
const render = ()=>{}
const hydrate = ()=>{}
return {
render,
hydrate
}
}
在导出render之前,我们可能还有很多逻辑,这就跟createReactive一样。
- 补丁 其实很多时候,渲染器并不是只渲染一次,我们会渲染多次。比如说当vnode变化的时候,
const renderer = createRenderer()
renderer.render(oldNode,`#app`)
renderer.render(newNode,`#app`)
这个时候,就需要对比新旧节点之间的不同,找到最小更新的子树,这个过程就称之为打补丁,就跟游戏里发现bug,或者更新新地图一样,我们不需要完整的更新整个游戏,我们只需要更新变化的部分,这一部分称之为patch,而对比新旧vnode的算法就称之为diff