《Vuejs设计与实现》8.1 挂载子节点和元素的属性

137 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情

上一章很短,只要讲了一下渲染器的基本概念,这一章开始才是渲染器的具体设计与分析,希望大家也能通过这一章实现出来自己的渲染器。

本章的标题为挂载与更新,是渲染器中最核心的功能,挂载指的是虚拟dom第一次转换为真实dom,更新就是指虚拟dom变化后,真实dom也需要跟着变化。

我们之前定义过一个vnode,但那个结构很简单,实际上,vnode应该也是一个树形结构,下面这段代码翻译过来就是<div><p>123</p></div>

const vnode = {
 type:'div',
 children:[
     {
         type:'p',
         children:'123'
     }
 ]
}

为了渲染这个vnode,我们就需要修改一下mountElement方法,这里不再是一个创建元素就完事了,需要递归children,去渲染所有子节点。

image.png

我们新增了一个当children是数组时的判断,然后在那里面递归这个数组,把子节点的内容,更新到div下,这里要尤其注意,不能更新到container下,container是你所有vnode转换完成之后需要放在哪里。

这里便完成一个简单的挂载函数,然后我们看一下如何表达元素的属性。如果为了简单,我们可以把元素的属性放到一个属性里,但实际上,我更建议把结构拍平,减少层级,这样无形中就减少我们许多的bug

image.png

在设置元素属性时,我和书里用的一样,都是原生js的setAttribute方法。虽然我们可以直接设置元素的属性,比如dom.id = 'a',但是这里很多意外情况我们都要去处理,不如直接用原生的方法比较划算.

而且,从原理上讲,类似于直接赋值是不对dom.id = 'a',dom并不是一个对象,它只是一个类似对象的结构,我们还是要是使用dom定义的一些方法去操作dom.