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的生成流程,对我们对整个框架或者我们自己来封装函数还是有帮助的!

相关推荐
耶啵奶膘31 分钟前
uniapp+firstUI——上传视频组件fui-upload-video
前端·javascript·uni-app
视频砖家1 小时前
移动端Html5播放器按钮变小的问题解决方法
前端·javascript·viewport功能
lyj1689971 小时前
vue-i18n+vscode+vue 多语言使用
前端·vue.js·vscode
小白变怪兽3 小时前
一、react18+项目初始化(vite)
前端·react.js
ai小鬼头3 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
墨菲安全4 小时前
NPM组件 betsson 等窃取主机敏感信息
前端·npm·node.js·软件供应链安全·主机信息窃取·npm组件投毒
GISer_Jing4 小时前
Monorepo+Pnpm+Turborepo
前端·javascript·ecmascript
天涯学馆4 小时前
前端开发也能用 WebAssembly?这些场景超实用!
前端·javascript·面试
我在北京coding5 小时前
TypeError: Cannot read properties of undefined (reading ‘queryComponents‘)
前端·javascript·vue.js
前端开发与ui设计的老司机5 小时前
UI前端与数字孪生结合实践探索:智慧物流的货物追踪与配送优化
前端·ui