Vue3中runtime-dom的实现-详细步骤

Vue为了解耦,将逻辑分成了两个模块

  • 运行时 (不依赖平台的browser),主要靠的是虚拟dom,它是可以跨平台的
  • 针对不同平台的运行时,vue就是针对浏览器平台的
  • runtime-dom提供一个渲染器,这个渲染器可以渲染虚拟dom节点到指定的容器中。

官方提供

Vue3中runtime-dom的实现-详细步骤_第1张图片

  • 根据用户传入的内容进行渲染

我们实现这个runtime-dom,创建runtime-dom文件夹

Vue3中runtime-dom的实现-详细步骤_第2张图片

创建src文件夹,下面创建index.ts,以及nodeOps.ts提供一些对节点的操作

插入节点

Vue3中runtime-dom的实现-详细步骤_第3张图片

  • anchor是插入参照物,可以为null,当anchor参数为null的时候,inserBefore等同于appendChild

创建元素

image.png

创建文本

image.png

删除节点

Vue3中runtime-dom的实现-详细步骤_第4张图片

设置元素内容

image.png

设置文本节点

image.png

查询节点

image.png

查询父节点

image.png

查询兄弟节点

image.png

上述是对节点的一些操作,下面我们来写对属性的一系列操作,创建patchProp.ts文件以及ptachProp需要调用的一些方法单独抽离的文件

Vue3中runtime-dom的实现-详细步骤_第5张图片

编写patchProp方法

Vue3中runtime-dom的实现-详细步骤_第6张图片

整合nodeOps和patcProp

Vue3中runtime-dom的实现-详细步骤_第7张图片

我们现在来详细写patchProp

  • 首先判断key的类型,分别交由不同的函数处理
  • 区分是class、style、事件和普通属性

Vue3中runtime-dom的实现-详细步骤_第8张图片

处理class

Vue3中runtime-dom的实现-详细步骤_第9张图片

  • 新改了值直接覆盖class
  • 新值是null,说明是删除操作,直接删除

处理style

Vue3中runtime-dom的实现-详细步骤_第10张图片

  • 循环最新值,把所有新值全部覆盖即可
  • 去除之前有的,新的没有的属性

处理事件

Vue3中runtime-dom的实现-详细步骤_第11张图片

如果没绑定过事件

  • 我们可以在元素上绑定一个_vei来记录元素绑定过的事件
  • 判断这个事件名是否存在,如果不存在,拿到新事件名字,on后面的值
  • 然后判断当前的新的事件是否有值,如果有值,我们用createInvoker处理事件值后,缓存到invokers中
  • 然后绑上事件
  • 如果新设置的事件值为空,那么就解绑事件,然后清空缓存区里这个事件
  • createInvoker这种写法有利于我们换绑事件,如果不这样写,那么我们每次更改事件的时候都需要先解绑,再绑新事件。

如果绑定过事件并且也设置了新值

  • 更换缓存区中该事件invoker的value值,更改为新值就可以了
  • createInvoker里为每一个事件创造了一个空函数,这个空函数的返回值调用这个空函数的value,而我们设置的事件就存在这个空函数的value属性上,这种操作有利于我们换绑事件

处理属性

Vue3中runtime-dom的实现-详细步骤_第12张图片

  • 如果新值有值,我们就直接设置到元素上
  • 如果没有,我们就删掉

runtime-dom还提供一个api,render

Vue3中runtime-dom的实现-详细步骤_第13张图片

  • render内部帮我们调用createRenderer后调用它的render进行渲染

createRenderer方法和h方法其实都不是在runtime-dom里实现,他俩是在runtime-core里实现的,因为渲染器他们本身是和平台无关的,你给我的是dom渲染还是canvas等,他们是不关心的

我们现在创建runtime-core模块

Vue3中runtime-dom的实现-详细步骤_第14张图片

我们下一章再实现h方法和createVnode方法

总结

runtime-dom本质上没做什么,它只是封装了一些平台对应的代码,它封装好以后,内部去调用创建渲染器去进行一个渲染,那具体怎么渲染是内部去做的,内部runtime-core去根据你传进来的一些属性操作、事件操作和dom操作等等方法,把传进来元素生成的vnode虚拟节点,然后放进对应的容器中就可以了。所以runtime-dom跟平台有关,而runtime-core跟平台无关。

你可能感兴趣的:(前端,javascript,大数据)