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


    节点的更新与删除

    在前面的文章中,我们已经能够对简单的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
  • 相关阅读:
    图扑软件用数据可视化形式告诉你,楼宇建设如何数字化转型
    李想的理想,不太「理想」
    self.register_buffer方法使用解析(pytorch)
    单播以及多播的书写实验
    强化学习之策略函数学习
    面试碰壁15次!作为一个已经27岁的测试工程师,未来在何方....
    MyBatis
    【会议征稿,CPS出版】第四届管理科学和软件工程国际学术会议(ICMSSE 2024,7月19-21)
    微服务学习之——nacos安装部署
    Monaco Editor 实现一个日志查看器
  • 原文地址:https://blog.csdn.net/qq_53225741/article/details/126957595