【拆解Vue3】渲染器是如何实现的(下篇)?

本文深入探讨Vue3渲染器的实现,包括节点的更新与删除,利用diff算法优化性能。此外,介绍了如何处理多个子节点的渲染,以及节点属性与事件的设置,通过标准化函数和事件监听器增强DOM操作。最后,推荐了一篇关于Vue开发技巧的总结文章。
摘要由CSDN通过智能技术生成

节点的更新与删除

在前面的文章中,我们已经能够对简单的vnode进行渲染。但前面我们实习的渲染是一次性的,实际开发中,我们需要重新渲染复杂节点的能力。为了实现这一点,我们考虑对前面实现的代码进行重构。先从创建渲染器的代码出发。

const renderer = createRender(DOMOptions)
renderer.render(vnode, document.querySelector('#app')) // (1)
renderer.render(newVNode, document.querySelector('#app')) // (2)
renderer.render(null, document.querySelector('#app')) // (3) 

在上面这段示例中,我们定义了一个构造器,(1)处传入vnode节点进行了初次渲染,(2)处给出了一个新的newVNode节点进行了更新,(3)处传入null卸载已经渲染的节点。

这里需要着重说明的是更新。最简单暴力的更新方式是删除旧的DOM,重新渲染新的DOM。但是不要忘了,虚拟DOM在性能上不如直接操作DOM来的快,之所以使用虚拟DOM,关键就在于虚拟DOM仅会进行必要的更新,通过减少更新的次数和规模,来间接提高前端项目的整体性能。Vue中使用diff算法来进行必要的更新,进行diff的前提是,我们需要保留旧vnode,与新vnode进行对比

function createRender(options) {const { createElement, setElementText, insert } = optionsfunction patch(oldNode, newNode, container) { // (4)if(!oldNode) {mountElement(newNode, container)}}function render(vnode, container) { if(vnode) { // (5)patch(container._vnode, vnode, container)}container._vnode = vnode // (6)}function mountElement(vnode, container) {const el = createElement(vnode.type)if(typeof vnode.children === 'string') {setElementText(el, vnode.children)}insert(el, container)}return {render}
} 

按照上面的思路,在(4)处新增了一个patch函数,并在render中调用该函数。在patch中,我们需要提供新DOM与旧DOM进行对比,在(6)处我们特地利用container保留了挂载在container上的vnode。重构后,我们就可以利用patch的参数来判断当前是要进行挂载,更新还是删除。

  • 挂载:oldNode为空,newNode不为空;
  • 更新:oldNode不为空,newNode不为空;
  • 删除:oldNode
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值