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

相关推荐
liangshanbo12153 小时前
写好 React useEffect 的终极指南
前端·javascript·react.js
哆啦A梦15886 小时前
搜索页面布局
前端·vue.js·node.js
_院长大人_6 小时前
el-table-column show-overflow-tooltip 只能显示纯文本,无法渲染 <p> 标签
前端·javascript·vue.js
哆啦A梦15887 小时前
axios 的二次封装
前端·vue.js·node.js
阿珊和她的猫7 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
yinuo7 小时前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端
snow@li8 小时前
html5:拖放 / demo / 拖放事件(Drag Events)/ DataTransfer 对象方法
前端·html·拖放
浪裡遊9 小时前
Nivo图表库全面指南:配置与用法详解
前端·javascript·react.js·node.js·php
漂流瓶jz10 小时前
快速定位源码问题:SourceMap的生成/使用/文件格式与历史
前端·javascript·前端工程化
samroom10 小时前
iframe实战:跨域通信与安全隔离
前端·安全