vue3源码学习-runtime 运行时

前言

距离上一篇源码学习已经很长时间了,一件事情一旦放下了,再捡起来就有点费劲了,可能也是因为离职变动与薪资维权的原因吧,导致现在已经无法沉下心去学习一些稍微难点的东西,那这篇就聊一些简单的概念东西。

虚拟DOM

这个问题在面试中也经常会问到,如果是vue相关的技术面试,问完虚拟DOM后会应该会追问vue2与vue3的diff算法有什么不同

虚拟dom的概念

虚拟dom本质上就是个js对象,用来表述真实dom的结构,然后通过渲染器,将页面结构生成出来

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>我是一个div,里面只有内容</div>
   <script>
    const dom={
        type:'div',
        children:'我是一个div,里面只有内容'
    }
   </script>
</body>
</html>

vue2 与 vue3 的diff算法

  • vue2 是通过对旧节点列表建立一个 { key, oldVnode } 的映射表,然后遍历新节点列表的剩余节点,根据newVnode.key在旧映射表中寻找可复用的节点,然后打补丁并且移动到正确的位置。

  • vue3 则是建立一个存储新节点数组中的剩余节点在旧节点数组上的索引的映射关系数组,建立完成这个数组后也即找到了可复用的节点,然后通过这个数组计算得到最长递增子序列,这个序列中的节点保持不动,然后将新节点数组中的剩余节点移动到正确的位置

用虚拟 dom 结构来生成页面

创建更新逻辑也比较简单,如果没有老节点,则直接创建挂载,如果有老节点,则暴力清除节点,再重新生成,进行挂载。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
   <script>
    const Vnode1={
        type:'div',
        children:'我是一个div,里面只有初始化内容'
    }
    const Vnode2={
        type:'h1',
        children:'我是一个h1,存放更新的内容'
    }
    const  app=document.querySelector('#app');

    const render=(oldVnode,newVnode,container)=>{
        if(oldVnode){//有老节点,说明是进行更新操作,则清除根节点,再进行生成
            unmount(container)
        }
        mount(newVnode,container)
    }
    // 创建节点
    const  mount=(newVnode,container)=>{
       const vnode=document.createElement(newVnode.type)
       vnode.innerHTML=newVnode.children
       container.appendChild(vnode)
    }
    const unmount=(container)=>{
        container.innerHTML=''
    }
    render(null,Vnode1,app)
    setTimeout(()=>{
        render(Vnode1,Vnode2,app)
    },5000)
   </script>
</body>
</html>

在vue3 中使用虚拟dom生成页面

通过h函数生成 虚拟 dom 节点,通过 render 函数进行页面挂载渲染。可以和我们上面的流程对比一下

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
    <div id="app"></div>
    <script>
        const {render,h}=Vue
        const vnode=h('div',{class:'container',onclick:()=>{alert('触发点击事件')}},'我是vnode')
        console.log(vnode)
        //常用到以下三个属性,第四个属性为标记,在props 中可以定义我们需要的任何属性
        // {
        //     children: "我是vnode",
        //     props: {class: 'container'},
        //     type: "div",
        //     __v_isVNode: true
        // }
        render(vnode,document.querySelector('#app'))
    </script>
</body>
</html>

最后

本篇文章比较简单,vue中虚拟dom的生成流程,对我们对整个框架或者我们自己来封装函数还是有帮助的!

相关推荐
驳是几秒前
一个组件,提升 react-router 开发的幸福感
前端·preact
GreenTea7 分钟前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
星云API技术支持13 分钟前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信
京东云开发者34 分钟前
81.8 秒的视频,我们改了 15 个版本:一次纯 Codex 驱动的 AI-native 视频实践
前端·aigc
Csvn1 小时前
TypeScript 大型项目架构:从单体 tsconfig 到分层可扩展的工程
前端
计算机魔术师3 小时前
Dario Amodei 发文呼吁为前沿 AI 降速并提出三点计划
前端
计算机魔术师3 小时前
OpenAI的AI代理偷偷给RubyGems下毒,我们却毫无察觉
前端
甲维斯3 小时前
0代码,0建模,3句话开发一个3D游戏!
前端·游戏·游戏开发
IT_陈寒3 小时前
Vue的响应式更新把我坑惨了,原来问题出在这
前端·人工智能·后端
tingke3 小时前
别再堆 AGENTS.md 了:前端团队的 Agent 上下文分层落地指南
前端