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

这篇具有很好参考价值的文章主要介绍了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 = childChanges
  
  return newTree
}

// 最终只会更新 span 的类名变化 
const newVDOM = diff(oldVDOM, newVDOM) 

两者的diff算法的区别

Vue 和 React 虽然都采用了虚拟 DOM 和 diff 算法,但在具体的 diff 实现上还是有一些区别的:文章来源地址https://www.toymoban.com/news/detail-580822.html

  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框架如何实现组件更新,原理是什么?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • React、Vue3中父组件如何调用子组件内部的方法

    当父组件需要调用子组件的方法时,可以通过useImperativeHandle钩子函数实现。以下例子是ts实现方式。 在子组件中使用 useImperativeHandle 钩子,将指定的方法暴露给父组件,以便父组件可以通过子组件的引用来调用该方法。 在子组件中使用了 useImperativeHandle 钩子将 someMethod 方法

    2024年02月16日
    浏览(35)
  • 面试题:react、 vue中的key有什么作用? (key的内部原理)

    1.虚拟DOM中key的作用: key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DON】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下: 2.对比规则: (1). 旧虚拟DOM 中找到了与 新虚拟DOM 相同的key: .若虚拟DOM中内容没变,直接使

    2024年02月04日
    浏览(37)
  • Mobx在非react组件中修改数据,在ts/js中修改数据实现响应式更新

    我们都之前在封装mobx作为数据存储的时候,使用到了useContext作为包裹,将store变成了一个hooks使用,封装代码: 但是我们都知道hooks只能在函数组件中或者hooks中使用,不能在ts/js代码中使用,但是我这里有一个需求,想每次发送接口请求的时候,做一个后置处理器,用于获取

    2024年02月11日
    浏览(48)
  • 如何使用前端框架(React、Angular、Vue.js等)?该如何选择?

    聚沙成塔·每天进步一点点 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一个系统而

    2024年02月07日
    浏览(60)
  • 一文搞定:前端如何选择Angular、React和Vue三大主流框架

    在前端开发领域,目前最流行的三个框架是Angular、React和Vue.js。这些框架非常高效,并且它们各自具有一系列的优缺点。 在AI辅助编程工具 CodeGeeX 的后台中,也看到有大量的前端开发者使用这三个框架,并且Vue的使用率在 CodeGeeX 的后台中,持续走高。接下来我们针对Angular、

    2024年02月09日
    浏览(56)
  • 什么是Vue组件?如何创建和使用组件?

    啥是组件? 组件就是Vue应用中的小模块,可以重复使用的代码块。组件使得开发大型应用更加容易,因为你可以把代码分成多个小块,每个小块都负责特定的任务,就像搭乐高积木一样。 创建组件 在Vue中创建组件有两种方式: 注册组件 使用Vue.component()方法注册一个全局组

    2024年02月06日
    浏览(48)
  • vue中组件动态传值,实现数据实时更新

    在一些项目需求中需要父组件向子组件动态传值,比如父组件动态通过axios获取数据,然后传给子组件,子组件根据拿到的数据进行展示。 props传值的时候,只会首次传递绑定的值,不会变化 方式1 利用watch监听props变化 方式2 利用ref获取子组件,调用子组件的方法将值传递过

    2024年02月16日
    浏览(51)
  • 前端Vue篇之v-model 是如何实现的,语法糖实际是什么?v-model 可以被用在自定义组件上吗?如果可以,如何使用?

    v-model 在 Vue.js 中扮演着重要的角色,实现了表单输入和应用状态之间的双向数据绑定。其具体实现方式取决于所绑定元素的类型。 作用在表单元素上 : 当 v-model 用于表单元素(如 input、textarea)时,它动态绑定了 input 的 value 到指定的变量,并在触发 input 事件时动态更新这

    2024年04月28日
    浏览(42)
  • webpack基础知识六:说说webpack的热更新是如何做到的?原理是什么?

    一、是什么 HMR全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用 例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失 如果使用的

    2024年02月13日
    浏览(40)
  • Vue.js 中的异步组件是什么?如何使用异步组件?

    在 Vue.js 中,异步组件是一种延迟加载组件的方式,可以大大提高应用程序的性能和加载速度。本文将介绍 Vue.js 中异步组件的概念、优势以及如何使用异步组件。 在传统的 Vue.js 开发中,组件是在应用程序启动时就立即加载的。这种方式虽然简单,但是会导致应用程序的初始

    2024年02月12日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包