当前位置: 首页 > news >正文

React、Vue框架如何实现组件更新,原理是什么?

引言

React 和 Vue 都是当今最流行的前端框架,它们都实现了组件化开发模式。为了优化性能,两者都采用了虚拟DOM技术。当组件状态发生改变时,它们会使用虚拟DOM进行局部渲染比对,只更新必要的DOM节点,从而避免重新渲染整个组件树。本文将从React和Vue的组件更新原理入手,剖析两者虚拟DOM difer算法的异同点。React通过comparing virtual DOM components and re-rendering only difference,而Vue通过响应式依赖追踪确定组件invalidated状态。尽管两者技术实现不同,但目的都是实现增量更新提高性能。本文还将通过代码实例,说明两者的Domin difer流程、对比粒度、更新触发等关键区别。读者将对React和Vue增量更新的内在原理有更深的理解,学会在实践中根据应用场景选择更合适的框架。

React、Vue如何实现组件更新

React和Vue是两个流行的JavaScript库,用于构建用户界面。它们都有自己的组件,下面将简单介绍一下更新原理。

React的组件更新机制:
在React中,组件更新是由虚拟DOM(Virtual DOM)和diff算法驱动的。当组件的状态(state)或属性(props)发生变化时,React会进行虚拟DOM的重新渲染,并将新的虚拟DOM与旧的虚拟DOM进行比较,找出需要更新的部分,然后只更新这些部分到实际的DOM。

React的组件更新流程如下:

  1. 组件状态或属性发生变化。
  2. React调用组件的render()方法重新渲染虚拟DOM。
  3. React将新的虚拟DOM与旧的虚拟DOM进行比较,找出需要更新的部分。
  4. React通过最小化DOM操作,只更新需要变化的部分到实际的DOM。
  5. 组件更新完成,触发相应的生命周期方法(如componentDidUpdate)。

下面是一个简单的React组件的例子,展示了组件的更新机制:

import React, { Component } from 'react';class Counter extends Component {constructor(props) {super(props);this.state = {count: 0};}handleClick = () => {this.setState(prevState => ({count: prevState.count + 1}));}render() {return (<div><p>Count: {this.state.count}</p><button onClick={this.handleClick}>Increment</button></div>);}
}

在上面的例子中,当用户点击"Increment"按钮时,handleClick方法会更新组件的状态count。React会重新调用render()方法重新渲染虚拟DOM,并将新的虚拟DOM与旧的虚拟DOM进行比较,然后只更新变化的部分(这里是<p>Count: {this.state.count}</p>)到实际的DOM。

Vue的组件更新机制:
在Vue中,组件更新是由响应式系统驱动的。Vue使用了一种名为"依赖追踪"的机制,它会在组件渲染过程中追踪组件所依赖的数据,并建立起依赖关系。当依赖的数据发生变化时,Vue会通知相关的组件进行更新。
Vue的更新过程大致如下:

  1. 数据变化时,setter 触发依赖,标记组件为脏数据
  2. 在下一轮事件循环中,Vue 会调用 patch 函数,比对新旧虚拟 DOM 树
  3. 通过 diff 算法比较树的差异,得到需要更新的最小节点
  4. 只对变化的部分进行 DOM 操作,更新视图
    diff 算法的主要步骤是:
  • 对比新旧节点,是否为同一节点
  • 如果不是,直接替换该节点及子节点
  • 如果是,对比新旧节点的属性是否变化
  • 对比子节点,使用键值优化顺序复杂度
  • 递归对比所有子节点
    通过这种方式,Vue 可以只更新变化的部分,避免不必要的 DOM 操作。
    下面是一个简单的Vue组件的例子,展示了组件的更新机制:
<template><div><p>Count: {{ count }}</p><button @click="increment">Increment</button></div>
</template><script>
export default {data() {return {count: 0};},methods: {increment() {this.count++;}}
}
</script>

在上面的例子中,当用户点击"Increment"按钮时,increment方法会更新组件的数据count。Vue会检测到count的变化,并通知组件重新渲染。然后Vue使用虚拟DOM进行比较,只更新变化的部分(这里是<p>Count: {{ count }}</p>)到实际的DOM。

总结:
React和Vue都采用了类似的组件更新机制,它们都通过比较虚拟DOM或追踪依赖来实现高效的组件更新。React和Vue都使用虚拟DOM和diff算法,这些机制使得组件的更新变得高效,只更新必要的部分,提高了应用的性能。

React与Vue更新的区别

Vue

  • 使用数据响应系统,通过改变组件的数据属性来触发更新。
  • 当组件的 data、props、computed 等属性改变时,会触发 setter,标记组件为“脏”。
  • 在下一轮事件循环中,会批量触发这些“脏”组件的重新渲染。

React

  • 使用状态(state)和属性(props)来控制组件。
  • 当状态或属性改变时,会触发重新渲染。
  • React 使用 Virtual DOM 来提高性能,只会针对改变的组件进行最小化渲染。
    相同点
  • 两者都是声明式框架,通过状态/数据变化控制界面。
  • 都使用虚拟 DOM ,进行增量更新提高性能。
    区别
  • Vue 侧重响应式数据,React 更侧重状态管理。
  • Vue 使用模板,React 使用 JSX。
  • Vue 批量异步更新,React 同步更新。
  • Vue 依赖数据变化触发更新,React 通过 setState/useState 控制。
    总体来说,两者都使用了类似的虚拟DOM和增量更新机制,但在触发更新的方式上有差异。Vue 更加主动,而 React 更加显式地控制。

什么是Diff算法

diff 算法是虚拟 DOM 中用于增量更新的关键算法。它的主要作用是对比两棵虚拟 DOM 树的差异,运算出需要更新的最小量 DOM 操作。
diff 算法的基本步骤如下:

  1. 用虚拟 DOM 构建出新的DOM树(树A)
  2. 将新的DOM树与旧的DOM树(树B)进行对比找出差异
  3. 对比过程中,首先比较树A和树B的根节点
  4. 如果根节点不相同,直接替换整个DOM树
  5. 如果根节点相同,再递归地对比和更新它的属性、子节点等
  6. 只更新变化的部分,不修改相同的节点
  7. 最后将变化渲染到真实DOM中
    diff算法的时间复杂度为O(n),它通过以下优化进一步提升了性能:
  • Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计
  • 拥有相同类的两个组件生成相似的树形结构,拥有较高的移位率
  • 通过唯一id区分节点,可以根据id直接判断两个节点是否相同

这里是一个简化的React Diff算法的实现示例。它包含了比较根节点、属性和子节点的逻辑。当根节点类型不同时,创建新节点并替换旧节点。当属性不同时,更新属性。对于子节点,通过遍历旧子节点和新子节点来进行比较,并进行递归的Diff算法调用。根据比较结果,进行增加、删除或更新相应的节点。

// 旧的虚拟DOM树
let oldVDOM = {tag: 'div',attrs: {id: 'container' },children: [{tag: 'p', attrs: {class: 'paragraph'}},{tag: 'span', attrs: {class: 'span'}}]
}// 新的虚拟DOM树 
let newVDOM = {tag: 'div',attrs: {id: 'container'},children: [{tag: 'p', attrs: {class: 'paragraph'}},{tag: 'span', attrs: {class: 'span-new'}} // span类名变化]
}// diff算法
function diff(oldTree, newTree) {// 1. 比较根节点if(oldTree.tag !== newTree.tag) {// 根节点不同,返回新树return newTree}// 2. 比较属性if(oldTree.attrs.id !== newTree.attrs.id) {// id变化,更新属性newTree.attrs = newTree.attrs }// 3. 比较子节点constchildChanges = []// 使用key进行优化oldTree.children.forEach(child => {const newChild = newTree.children.find(c => c.key === child.key)// 深度递归对比子节点const changedChild = diff(child, newChild)childChanges.push(changedChild)})newTree.children = childChangesreturn newTree
}// 最终只会更新 span 的类名变化 
const newVDOM = diff(oldVDOM, newVDOM) 

两者的diff算法的区别

Vue 和 React 虽然都采用了虚拟 DOM 和 diff 算法,但在具体的 diff 实现上还是有一些区别的:

  1. 对比粒度不同
  • Vue 的虚拟 DOM 是Render 函数渲染生成的,对比粒度为组件级别。
  • React 的虚拟 DOM 是由 React元素构成,对比粒度为节点级别。
  1. 处理方式不同
  • Vue 通过标记静态子树,可以重复使用不变的部分。
  • React 总是重新构造虚拟 DOM,对相同节点也会进行属性对比。
  1. 组件识别不同
  • Vue 通过组件的 name 属性识别组件是否相同。
  • React 通过组件 type 来判断是否为相同组件类型。
  1. key 的作用不同
  • Vue 主要用 key 管理可复用的元素。
  • React 主要用 key 匹配旧元素与新元素。
  1. 事件处理不同
  • Vue 可以精确知道哪个事件发生变化,只更新事件。
  • React 每次都需要重新绑定事件,对组件影响较大。
    综上,Vue 和 React 虽然概念上都是通过虚拟 DOM + diff 实现增量更新,但在具体实现和优化上还是有一定区别的。

相关文章:

React、Vue框架如何实现组件更新,原理是什么?

引言 React 和 Vue 都是当今最流行的前端框架,它们都实现了组件化开发模式。为了优化性能,两者都采用了虚拟DOM技术。当组件状态发生改变时,它们会使用虚拟DOM进行局部渲染比对,只更新必要的DOM节点,从而避免重新渲染整个组件树。本文将从React和Vue的组件更新原理入手,剖析两…...

常见面试题之设计模式--策略模式

1. 概述 先看下面的图片&#xff0c;我们去旅游选择出行模式有很多种&#xff0c;可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。 作为一个程序猿&#xff0c;开发需要选择一款开发工具&#xff0c;当然可以进行代码开发的工具有很多&#xff0c;可以选择Idea进行开发&a…...

redis多key问题

多key问题指的是在Redis中存在大量的key&#xff0c;如果这些key过多&#xff0c;超过了Redis可以容纳的内存大小&#xff0c;那么数据会被保存在交换空间&#xff08;swap区&#xff09;&#xff0c;这会导致性能下降。 Redis是一种基于内存的缓存数据库&#xff0c;它的性能…...

kafka第三课-可视化工具、生产环境问题总结以及性能优化

一、可视化工具 https://pan.baidu.com/s/1qYifoa4 密码&#xff1a;el4o 下载解压之后&#xff0c;编辑该文件&#xff0c;修改zookeeper地址&#xff0c;也就是kafka注册的zookeeper的地址&#xff0c;如果是zookeeper集群&#xff0c;以逗号分开 vi conf/application.conf 启…...

2_Apollo4BlueLite中断控制器NVIC

1.概述 Apollo4BlueLite 的中断控制器是采用 ARM Cortex-M4 内核&#xff0c;并集成了 NVIC&#xff08;Nested Vectored Interrupt Controller&#xff0c;嵌套向量中断控制器&#xff09;作为其中断控制器。 NVIC 是 ARM Cortex-M 系列处理器中常用的中断控制器&#xff0c…...

WAIC2023:图像内容安全黑科技助力可信AI发展

目录 0 写在前面1 AI图像篡改检测2 生成式图像鉴别2.1 主干特征提取通道2.2 注意力模块2.3 纹理增强模块 3 OCR对抗攻击4 助力可信AI向善发展总结 0 写在前面 2023世界人工智能大会(WAIC)已圆满结束&#xff0c;恰逢全球大模型和生成式人工智能蓬勃兴起之时&#xff0c;今年参…...

微信小程序quickstartFunctions中云函数的应用

1、在quickstartFunctions文件中新建文件夹和文件 2、index.js 文件书写 const cloud require(wx-server-sdk);cloud.init({env: cloud.DYNAMIC_CURRENT_ENV }); const db cloud.database();// 链表查询试卷和对应的题库 exports.main async (event, context) > {retu…...

Go学习 2、程序结构

2、程序结构 2.1 命名 一个名字必须以一个字母或下划线开头&#xff0c;后面可以跟任意数量的字母、数字或下划线。 大写字母和小写字母是不同的。 GO语言有25个关键字&#xff0c;关键字不能用于自定义名字。 还有大约30多个预定义名字&#xff0c;对应内建的常量、类型和函…...

SpringBoot整合JavaMail

SpringBoot整合JavaMail 简单使用-发送简单邮件 介绍协议 导入坐标 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>添加配置 spring:mail:host: smtp.qq.co…...

Spring6——入门

文章目录 入门环境要求构建模块程序开发引入依赖创建java类创建配置文件创建测试类运行测试程序 程序分析启用Log4j2日志框架Log4j2日志概述引入Log4j2依赖加入日志配置文件测试使用日志 入门 环境要求 JDK&#xff1a;Java17&#xff08;Spring6要求JDK最低版本是Java17&…...

【计算机视觉 | 目标检测 | 图像分割】arxiv 计算机视觉关于目标检测和图像分割的学术速递(7 月 17 日论文合集)

文章目录 一、检测相关(5篇)1.1 TALL: Thumbnail Layout for Deepfake Video Detection1.2 Cloud Detection in Multispectral Satellite Images Using Support Vector Machines With Quantum Kernels1.3 Multimodal Motion Conditioned Diffusion Model for Skeleton-based Vi…...

为什么需要GP(Global Platform)认证?

TEE之GP(Global Platform)认证汇总 一、为什么需要认证&#xff1f; 二、为什么是GP&#xff1f; 参考&#xff1a; GlobalPlatform Certification - GlobalPlatform...

eclipse 格式化代码 快捷键

在Eclipse中&#xff0c;可以使用以下快捷键来格式化代码&#xff1a; Windows/Linux快捷键&#xff1a;Ctrl Shift FMac快捷键&#xff1a;Command Shift F 按下相应的快捷键后&#xff0c;Eclipse将自动根据您的代码格式化偏好设置对代码进行格式化。请确保已经选择和配…...

深入探索Socks5代理与网络安全

简介 Socks5代理是一种网络协议&#xff0c;用于在客户端和服务器之间进行数据传输&#xff0c;它可以在网络层和传输层实现代理功能。与其他代理协议相比&#xff0c;Socks5代理更加灵活和安全&#xff0c;为爬虫任务和网络安全提供了重要支持。 Socks5代理的工作原理 Socks5…...

【NLP】如何使用Hugging-Face-Pipelines?

一、说明 随着最近开发的库&#xff0c;执行深度学习分析变得更加容易。其中一个库是拥抱脸。Hugging Face 是一个平台&#xff0c;可为 NLP 任务&#xff08;如文本分类、情感分析等&#xff09;提供预先训练的语言模型。 本博客将引导您了解如何使用拥抱面部管道执行 NLP 任务…...

网络安全(黑客)自学笔记

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一是市场需求量高&#xff1b; 二则是发展相对成熟入门…...

spring数据校验

数据校验 概述 在开发中&#xff0c;会存在参数校验的情况&#xff0c;如&#xff1a;注册时&#xff0c;校验用户名不能为空、用户名长度不超过20个字符&#xff0c;手机号格式合法等。如果使用普通方式&#xff0c;会将校验代码和处理逻辑耦合在一起&#xff0c;在需要新增一…...

因材施教,有道发布“子曰”教育大模型,落地虚拟人口语教练等六大应用

因材施教的教育宗旨下&#xff0c;大模型浪潮中&#xff0c;网易有道凭借其对教育场景的深入理解和对商业化的理性思考&#xff0c;为行业树立了垂直大模型的典范。 7月26日&#xff0c;教育科技公司网易有道举办了“powered by 子曰”教育大模型应用成果发布会。会上重磅推出了…...

golang waitgroup

案例 WaitGroup 可以解决一个 goroutine 等待多个 goroutine 同时结束的场景&#xff0c;这个比较常见的场景就是例如 后端 worker 启动了多个消费者干活&#xff0c;还有爬虫并发爬取数据&#xff0c;多线程下载等等。 我们这里模拟一个 worker 的例子 package mainimport (…...

单列模式多学两遍

单例模式 单例模式(Singleton Pattern&#xff0c;也称为单件模式)&#xff0c;使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点&#xff0c;该实例被所有程序模块共享。 定义单例类 ● 私有化它的构造函数&#xff0c;…...

从‘Hello World’到物联网:用Hi3861点灯程序,带你理解鸿蒙轻量级设备开发的核心流程

从‘Hello World’到物联网&#xff1a;用Hi3861点灯程序&#xff0c;带你理解鸿蒙轻量级设备开发的核心流程 在物联网设备开发领域&#xff0c;鸿蒙系统&#xff08;OpenHarmony&#xff09;正以其轻量级、高并发的特性吸引着越来越多的开发者。对于初学者而言&#xff0c;一个…...

告别重复劳动:OpenClaw+nanobot批量重命名与整理照片实战

告别重复劳动&#xff1a;OpenClawnanobot批量重命名与整理照片实战 1. 为什么需要自动化照片整理 每次旅行回来&#xff0c;面对相机和手机里混杂的几百张照片&#xff0c;整理工作总是让人头疼。手动创建文件夹、按日期地点分类、重命名文件——这些重复劳动不仅耗时&#…...

告别激光雷达?手把手教你用CRN低成本实现BEV 3D感知(附PyTorch代码)

低成本BEV 3D感知实战&#xff1a;用CRN实现相机-雷达融合&#xff08;附完整PyTorch代码&#xff09; 在自动驾驶和机器人领域&#xff0c;3D环境感知一直是核心技术瓶颈。传统激光雷达方案虽精度高&#xff0c;但成本动辄数万元&#xff0c;且受天气影响显著。我们团队经过半…...

OpenHarmony 5.0.2 音频驱动适配实战:从ADM配置到耳机/扬声器切换

1. OpenHarmony音频驱动适配背景与问题定位 最近在RK3568平台上适配OpenHarmony 5.0.2的音频功能时&#xff0c;遇到了一个典型问题&#xff1a;使用RK809音频芯片时&#xff0c;耳机可以正常发声&#xff0c;但内置扬声器完全没声音&#xff0c;而且插入耳机后扬声器也不会自动…...

使用Yolo 11进行定制化图像识别全流程

全流程预览 Label Studio标注 → 导出YOLO格式 → 编写data.yaml → 拆分数据集 → 模型训练 → 预测部署步骤工具/技术产出物数据标注Label Studio标注好的图片数据导出YOLO with imagesimages/ labels/配置文件data.yaml数据集配置数据拆分Python脚本train/val/test模型训练…...

BlueDot BME280库深度解析:嵌入式多传感器驱动实践

1. BlueDot BME280 库技术解析&#xff1a;面向嵌入式工程师的多传感器驱动实践指南BME280 是博世&#xff08;Bosch&#xff09;推出的高精度环境传感器&#xff0c;集成温度、相对湿度与气压三参数测量能力&#xff0c;广泛应用于气象站、IoT终端、无人机姿态补偿及室内环境监…...

阿里开源MGeo地址匹配:零基础3步搭建,开箱即用

阿里开源MGeo地址匹配&#xff1a;零基础3步搭建&#xff0c;开箱即用 1. 为什么你需要MGeo地址匹配&#xff1f; 地址数据混乱是每个数据工程师的噩梦。同一地点在不同系统中可能有十几种写法&#xff1a;"北京市海淀区中关村大街1号"、"北京海淀中关村1号&q…...

5大核心模块解锁Awesome Claude Skills:打造企业级AI工作流工具箱

5大核心模块解锁Awesome Claude Skills&#xff1a;打造企业级AI工作流工具箱 【免费下载链接】awesome-claude-skills A curated list of awesome Claude Skills, resources, and tools for customizing Claude AI workflows 项目地址: https://gitcode.com/GitHub_Trending…...

python vue基于hadoop的高校图书馆借阅阅读书目智慧推荐系统

目录技术架构设计数据采集与存储模块数据处理与分析模块推荐算法实现Vue前端开发系统部署方案测试与优化项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术架构设计 系统采用前后端分离架构&#xff0c;前端使用Vue.js框架开…...

Driver Store Explorer:Windows驱动管理的终极解决方案

Driver Store Explorer&#xff1a;Windows驱动管理的终极解决方案 【免费下载链接】DriverStoreExplorer Driver Store Explorer [RAPR] 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer Driver Store Explorer&#xff08;简称RAPR&#xff09;是一…...