Vue源码解析

news2024/11/27 5:34:41

【尚硅谷】Vue源码解析之虚拟DOM和diff算法

【Vue源码】图解 diff算法 与 虚拟DOM-snabbdom-最小量更新原理解析-手写源码-updateChildren]

文章目录

    • 2. snabbdom 简介 及 准备工作
      • 2.1 简介
      • 2.2 搭建初始环境
        • 1. 安装snabbdom
        • 2. 安装webpack5并配置
        • 3. 复制官方demo Example
    • 3. h函数的介绍与使用
      • 3.1 介绍
      • 3.2 使用h函数 创建虚拟节点
      • 3.3 使用patch函数 将虚拟节点上DOM树
      • 3.4 h函数嵌套使用,得到虚拟DOM树(重要)

2. snabbdom 简介 及 准备工作

2.1 简介

snabbdom(瑞典语,“速度”)是著名的虚拟DOM库,是diff算法的鼻祖
Vue源码借鉴了snabbdom
源码使用TypeScript写的https://github.com/snabbdom/snabbdom
从npm下载的是build出来的JavaScript版本
-D 是开发dev版本的依赖 -S是项目真正依赖

2.2 搭建初始环境

1. 安装snabbdom

npm init
npm install -D snabbdom

下载好的源码在node_modules
在这里插入图片描述
需要读取一些init等文件,使用webpack5,不能是webpack4(读取的地址不对)。接下来安装webpack5

2. 安装webpack5并配置

cnpm i -D webpack@5 webpack-cli@3 webpack-dev-server@3

配置webpack5
根目录下创建webpack.config.js

cnpm i -D webpack@5 webpack-cli@3 webpack-dev-server@3

“dev”: “webpack-dev-server” npm run dev实际跑的是npm run webpack-dev-server会读取webpack.config.js文件
在这里插入图片描述
webpack.config.js配置文件


module.exports = {
    // webpack5 不用配置mode
    // 入口
    entry: "./src/index.js",
    // 出口
    output: {
      // 虚拟打包路径,文件夹不会真正生成,而是在8080端口虚拟生成
      publicPath: "xuni",
      // 打包出来的文件名
      filename: "bundle.js",
    },
    // 配置webpack-dev-server
    devServer: {
      // 静态根目录
      contentBase: 'www',
      // 端口号
      port: 8080,
    },
  };
  

3. 复制官方demo Example

src/index.js

import {
  init,
  classModule,
  propsModule,
  styleModule,
  eventListenersModule,
  h,
} from "snabbdom";

const patch = init([
  // Init patch function with chosen modules
  classModule, // makes it easy to toggle classes
  propsModule, // for setting properties on DOM elements
  styleModule, // handles styling on elements with support for animations
  eventListenersModule, // attaches event listeners
]);

const container = document.getElementById("container");

const vnode = h("div#container.two.classes", { on: { click: function () { } } }, [
  h("span", { style: { fontWeight: "bold" } }, "This is bold"),
  " and this is just normal text",
  h("a", { props: { href: "/foo" } }, "I'll take you places!"),
]);
// Patch into empty DOM element – this modifies the DOM as a side effect
patch(container, vnode);

const newVnode = h(
  "div#container.two.classes",
  { on: { click: function () { } } },
  [
    h(
      "span",
      { style: { fontWeight: "normal", fontStyle: "italic" } },
      "This is now italic type"
    ),
    " and this is still just normal text",
    h("a", { props: { href: "/bar" } }, "I'll take you places!"),
  ]
);
// Second `patch` invocation
patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state

根目录创建www文件夹,内部有index.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="container"></div>
    <script src="/xuni/bundle.js"></script>
</body>
</html>

npm run dev跑起来
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3. h函数的介绍与使用

3.1 介绍

diff算法发生在 虚拟DOM上,新旧虚拟DOM的比较
h 函数产生虚拟节点
在这里插入图片描述
在这里插入图片描述
虚拟节点vnode的属性

{
	children: undefined// 子元素 数组
	data: {} // 属性、样式、key
	elm: undefined // 对应的真正的dom节点(对象),undefined表示节点还没有上dom树
	key: // 唯一标识
	sel: "" // 选择器
	text: "" // 文本内容
}

3.2 使用h函数 创建虚拟节点

3.3 使用patch函数 将虚拟节点上DOM树

src/index.js

import {
    init,
    classModule,
    propsModule,
    styleModule,
    eventListenersModule,
    h,
  } from "snabbdom";
  

  
var myVnode1 = h('a', {
    props: {
        href: "http://www.baidu.com",
        target: '_blank',
      }
}, '百度')
// const myVnode2 = h('div', '我是盒子' )
const myVnode3 = h('div', {class:{'box': true}},  '我是盒子')

console.log(myVnode1)
//   将虚拟节点渲染成真实节点 需要使用patch函数
const patch = init([
    // Init patch function with chosen modules
    classModule, // makes it easy to toggle classes
    propsModule, // for setting properties on DOM elements
    styleModule, // handles styling on elements with support for animations
    eventListenersModule, // attaches event listeners
  ]);
  
const container = document.getElementById("container");
patch(container, myVnode1)

在这里插入图片描述
console.log(myVnode1)的输出
在这里插入图片描述

3.4 h函数嵌套使用,得到虚拟DOM树(重要)

在这里插入图片描述

const myVnode4 = h('ul', [
    h('li', '苹果1'),
    h('li', '苹果2'),
    h('li', '苹果3'),
    h('li', '苹果4'),
])
console.log(myVnode1)
//   将虚拟节点渲染成真实节点 需要使用patch函数
const patch = init([
    // Init patch function with chosen modules
    classModule, // makes it easy to toggle classes
    propsModule, // for setting properties on DOM elements
    styleModule, // handles styling on elements with support for animations
    eventListenersModule, // attaches event listeners
  ]);
  
const container = document.getElementById("container");
patch(container, myVnode4)

在这里插入图片描述

const myVnode4 = h('ul', [
    h('li', '苹果1'),
    h('li', [
        h('div', [
            h('p', "香蕉皮"),
            h('p', "苹果皮")
        ])
    ]),
    h('li', h('span', '西瓜')),
    h('li', '番茄'),
])

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/620958.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IJCAI 2023 | 如何从离散时间事件序列中学习因果结构?

本文分享一篇我们在IJCAI 2023的最新工作&#xff0c;文章分析了在离散时间事件序列上存在的瞬时效应问题&#xff0c;提出了一种利用瞬时效应的结构霍克斯模型&#xff0c;且在理论上证明了事件序列上的瞬时因果关系同样是可识别的。 相关论文&#xff1a; Jie Qiao et al. “…

基于SpringBoot的家庭记账管理系统的设计与实现

摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

数据结构之线性表

1.线性表的定义 线性表是由n(n≥0)个类型相同的数据元素组成的有限 序列&#xff0c;记作:L &#x1d44e;0, &#x1d44e;1, ⋯ , &#x1d44e;&#x1d456; , ⋯ , &#x1d44e;&#x1d45b;−1 2 线性表的顺序存储结构实现 线性表的顺序存储结构称为顺序表&#xff08;…

2023年前端面试汇总-HTML

1. src和href的区别 src和href都是用来引用外部的资源&#xff0c;它们的区别如下&#xff1a; src表示对资源的引用&#xff0c;它指向的内容会嵌入到当前标签所在的位置。src会将其指向的资源下载并应用到文档内&#xff0c;如请求js脚本。当浏览器解析到该元素时&#xff…

HyperLogLog数据结构

基数计数(cardinality counting) 通常用来统计一个集合中不重复的元素个数&#xff0c;例如统计某个网站的UV&#xff0c;或者用户搜索网站的关键词数量。数据分析、网络监控及数据库优化等领域都会涉及到基数计数的需求。 要实现基数计数&#xff0c;最简单的做法是记录集合中…

34岁出来面试,还被拒绝有多惨?

我强烈建议大家定期去参加一下外面的面试&#xff0c;尤其是BAT大厂的面试&#xff0c;不要一直闷在公司里&#xff0c;不然你很容易被这个世界遗弃。 前言 昨天&#xff0c;我们小组长奉命去面了一个34岁的测试员。 去了大概半个多小时吧&#xff0c;回来后&#xff0c;他的…

图数据库(二):Java操作图数据库

在上篇文章中&#xff0c;我们介绍了什么是Neo4j&#xff0c;什么是Cypher以及Neo4j的使用&#xff0c;今天我们学习一下如何使用Java操作Neo4j图数据库。 Cypher查询 在使用Java操作Neo4j之前&#xff0c;我们先了解一点&#xff0c;Cypher语句简单查询。 本文使用的是Neo4j…

Flutter的状态管理之Provider

Provider简介 Flutter Provider是Flutter中一个非常流行的状态管理库&#xff0c;它可以帮助开发者更加方便地管理应用程序中的状态。Provider提供了一种简单的方式来共享和管理应用程序中的数据&#xff0c;并且可以根据数据的变化来自动更新UI界面。 Provider的核心思想是将…

网络协议——什么是RIP协议?工作原理是什么?

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 一、什么是RIP协议&#xff1f; 二、为什么要使用RIP&#xff1f; 三、RIP用在哪里&#xff1f; 四、RIP协议的工作原理 五、总结 …

Redis安装布隆过滤器

目录 1 什么是布隆过滤器1.1 布隆过滤器的原理1.2 布隆过滤器缺点 2 插件形式安装2.1 下载布隆过滤器插件 3 docker方式单机安装4 Redis集群部署安装4.1 创建目录4.2 redis配置文件4.3 配置docker-compose.yml文件4.4 启动布隆过滤器集群4.5 配置集群4.6 布隆过滤器常用命令4.7…

如何将simulink中的元件(光伏板)导入到plecs中使用

simulink中有一些元件在plecs中是没有的&#xff0c;如果想要直接使用simulink的库&#xff0c;可以这样操作&#xff1a; 1 新建mdl文件&#xff08;simulink的文件类型&#xff09;&#xff0c;并在该文件中搭建好想要的模型、元件&#xff08;只放想要导出的元件就可以了&…

商城检索 DSL

模糊匹配过滤&#xff08;按照属性、分类、品牌、价格区间、库存&#xff09;排序分页高亮聚合分析 一. 搜索关键字 检索字段&#xff1a;商品sku标题 “skuTitle” : “华为 HUAWEI Mate 30 Pro 亮黑色 8GB256GB麒麟990旗舰芯片OLED环幕屏双4000万徕卡电影四摄4G全网通手机”…

基于Java+SpringBoot+Vue前后端分离考试学习一体机设计与实现(视频讲解)

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

docker-compose单机容器集群编排

docker-compose dockerfile模板文件可以定义一个独立的应用容器&#xff0c;如果需要多个容器就需要服务编排。服务编排有很多技术方案 docker-compose开源的项目实现对容器集群的快速编排 docker-compose将所管理的容器分为三层&#xff0c;分别为工程&#xff0c;服务&#…

Jenkins+RF持续集成测试(三) 生成测试报告并发给指定人

在上一篇《定时更新SVN完成构建》中讲了定时从SVN拉取最新的测试脚本&#xff0c;并自动构建的过程。这篇我将介绍怎么配置测试robot报告&#xff0c;并发送给指定人群。 1、要发给指定人&#xff0c;首先需要在job配置&#xff0c;构建后操作中增加“Editable Email Notificat…

day3 ARM寄存器组织

目录 寄存器 ARM寄存器 专用寄存器 CPSR寄存器 寄存器 概念&#xff1a;寄存器是处理器内部的存储器&#xff0c;没有地址&#xff1b; 作用&#xff1a;一般用于暂时存放参与运算的数据和运算结果&#xff1b; 分类&#xff1a;包括通用寄存器、专用寄存器、控制寄存器&…

腾讯云数据库2022下半年本地部署市场收入同比增速达110%,远超市场平均水平

6月7日&#xff0c;记者获悉&#xff0c;据全球领先的IT市场研究和咨询公司IDC发布的《2022年下半年中国关系型数据库软件市场跟踪报告》显示&#xff0c;在Top 5厂商中&#xff0c;腾讯云数据库整体收入同比增速、本地部署模式收入同比增速均位列第一。 具体来看&#xff0c;…

ChatPPT一键制作PPT,效果拉满~

&#x1f4a7; C h a t P P T 一 键 制 作 P P T &#xff0c; 效 果 拉 满 &#xff01; \color{#FF1493}{ChatPPT一键制作PPT&#xff0c;效果拉满&#xff01;} ChatPPT一键制作PPT&#xff0c;效果拉满&#xff01;&#x1f4a7; &#x1f337; 仰望天空&#xf…

网络安全面试题集及答案整理汇总(2023最新版详细)

前言 随着国家政策的扶持&#xff0c;网络安全行业也越来越为大众所熟知&#xff0c;想要进入到网络安全行业的人也越来越多。 为了拿到心仪的Offer之外&#xff0c;除了学好网络安全知识以外&#xff0c;还要应对好企业的面试。 作为一个安全老鸟&#xff0c;工作这么多年&…

如何安装intellij IDEA

想要自学编程&#xff0c;又不知道从那开始&#xff0c;百度找起来比较费劲&#xff0c;现在有个比较便捷的途径&#xff0c;就是直接问chatgpt。 在询问chatgpt后&#xff0c;得知目前比较流行的开发工具是intellij IDEA&#xff0c;然后问了chatgpt怎么下载这个工具&#xf…