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

相关推荐
涵信42 分钟前
第一节 基础核心概念-TypeScript与JavaScript的核心区别
前端·javascript·typescript
谢尔登1 小时前
【React】常用的状态管理库比对
前端·spring·react.js
编程乐学(Arfan开发工程师)1 小时前
56、原生组件注入-原生注解与Spring方式注入
java·前端·后端·spring·tensorflow·bug·lua
小公主1 小时前
JavaScript 柯里化完全指南:闭包 + 手写 curry,一步步拆解原理
前端·javascript
姑苏洛言3 小时前
如何解决答题小程序大小超过2M的问题
前端
GISer_Jing4 小时前
JWT授权token前端存储策略
前端·javascript·面试
开开心心就好4 小时前
电脑扩展屏幕工具
java·开发语言·前端·电脑·php·excel·batch
拉不动的猪4 小时前
es6常见数组、对象中的整合与拆解
前端·javascript·面试
GISer_Jing4 小时前
Vue Router知识框架以及面试高频问题详解
前端·vue.js·面试
小白变怪兽4 小时前
实现图片懒加载
前端