【Vue3源码学习】— CH2.8 Vue 3 响应式系统小结

Vue 3 响应式系统小结

    • 1.核心概念
      • 1.1 Proxy和Reflect
      • 1.2 响应式API
      • 1.3 依赖收集与更新触发
      • 1.4 触发更新(Triggering Updates):
      • 1.5 副作用函数(Effect)
      • 1.6 计算属性和观察者
      • 1.7 EffectScope
      • 1.8 性能优化:
    • 2. 手动实现简单响应式系统
    • 3. 发散思考

Vue 3 的响应式系统利用现代 JavaScript 的特性,如 Proxy 和 Reflect,为开发者提供了一个强大且灵活的工具集,以简化响应式编程。这一节回顾了我们学习的关键概念,并展示了如何手动构建一个简单的响应式系统。

1.核心概念

1.1 Proxy和Reflect

Vue 3 采用 Proxy 来拦截对象操作,配合 Reflect 保证操作的默认行为。这使得 Vue 能够在数据访问或修改时执行自定义逻辑,实现自动的依赖跟踪和更新触发。

1.2 响应式API

通过 reactive、ref 等 API,Vue 允许开发者把普通对象转换成响应式对象,实现数据的自动更新。

1.3 依赖收集与更新触发

Vue 内部通过 track 和 trigger 函数管理依赖关系,确保数据变化时能自动通知并执行相关的副作用函数。

1.4 触发更新(Triggering Updates):

当响应式数据被修改时,Vue 通过trigger函数查找所有依赖于这个数据的副作用函数,并重新执行它们。这样,基于这些数据的视图或其他副作用就会被更新。

1.5 副作用函数(Effect)

Vue 3通过effect函数包装副作用(如渲染函数、计算属性等),使其能够自动响应数据的变化。每个副作用在执行时都会被ReactiveEffect类的实例封装,这个实例记录了副作用函数以及它所依赖的数据。

1.6 计算属性和观察者

计算属性和观察者也是通过副作用系统实现的。计算属性(computed)和观察者(watch)提供了更细粒度的响应式控制,优化性能同时保持数据更新的逻辑清晰。

1.7 EffectScope

effectScope 管理副作用的生命周期,尤其是在组件卸载时自动停止副作用,避免内存泄漏。

1.8 性能优化:

Vue 3的响应式系统使用了诸如WeakMap和Map这样的原生数据结构来存储依赖关系,减少了内存的使用,并优化了垃圾回收。同时,通过避免不必要的副作用执行和精细的依赖追踪,提高了更新的效率。

2. 手动实现简单响应式系统

在完整的学习了Vue3源码响应式系统部分之后,我们尝试以手动创建一个简化版的响应式系统来加深理解:

//响应式逻辑
let activeEffect = null;
const targetMap = new WeakMap();

const reactive = (target) => {
  return new Proxy(target, handler);
}
const handler = {
  get(target, property, receiver) {
    track(target, property);
    return Reflect.get(target, property, receiver); // 确保返回属性的值
  },
  set(target, property, value, receiver) {
    const result = Reflect.set(target, property, value, receiver); // 设置新值
    trigger(target, property, value);
    return result;
  }
}
const track = (target, property) => {
  if (!activeEffect) return;

  let depsMap = targetMap.get(target);
  if (!depsMap) {
    depsMap = new Map();
    targetMap.set(target, depsMap);
  }
  let deps = depsMap.get(property);
  if (!deps) {
    deps = new Set(); // 使用 Set 存储唯一的副作用函数
    depsMap.set(property, deps);
  }
  deps.add(activeEffect);
}
const trigger = (target, property) => {
  const depsMap = targetMap.get(target)
  if (!depsMap) {
    return;
  }
  const deps = depsMap.get(property);
  deps.forEach(effectFn => {
    effectFn.run();
  })
}
class ReactiveEffect {
  constructor(fn) {
	this.fn=fn;
  }
  run() {
    try {
      activeEffect = this;
      this.fn();
    } finally {
      activeEffect = null;
    }
  }
}
const effect = (fn) => {
  const _effect = new ReactiveEffect(fn);
  _effect.run();
  return _effect;
}

//应用
const status = reactive({
  count: 0
});
effect(() => {
  console.log(status.count);
});
status.count++;

//执行和输出:
//0
//0

3. 发散思考

Vue的响应式系统和Backbone中的数据监听、发布-订阅模式在目的上确实非常相似,都是为了实现数据变化时自动更新视图或执行某些操作。它们都遵循了观察者模式的基本原则,即当数据(被观察者)发生变化时,能够自动通知所有依赖于这些数据的订阅者(观察者),并触发相应的更新逻辑。

Vue 的响应式系统与 Backbone 等传统模式的主要区别在于自动化的依赖追踪与更新触发机制。Vue的响应式系统利用ES6的Proxy和内部的依赖追踪机制来自动捕获依赖关系,并在响应式数据变化时自动触发更新。Vue 的设计使得开发者能够专注于业务逻辑,而无需手动管理数据监听和更新,极大地提升了开发效率和应用性能。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库-root密码丢失的重置方案(win11环境)

当在windows系统中安装的mysql由于操作不当,或者密码遗忘,今天测试了一下,可以用以下方法重置root的密码。 mysqlwindows环境root密码重置问题 在win10/11环境下mysql8密码遗忘后的重置密码方案。 停止mysql服务 查找windows中的mysql服务名称…

软考高级架构师:性能评价方法概念和例题

一、AI 讲解 性能评价是衡量计算机系统或其组件在指定条件下执行预期任务的有效性的一种方式。性能评价的方法主要可以分为几种,每种方法都有其特点和适用场景。 性能评价方法 方法描述时钟频率法通过计算机的时钟频率来评估性能,时钟频率越高&#x…

morkdown语法转微信公众号排版(免费)

morkdown语法转微信公众号排版(免费) 源码来自githab,有些简单的问题我都修复了。大家可以直接去找原作者的源码,如果githab打不开就从我下载的网盘里下载吧。 效果

LeetCode 热题 100 | 动态规划(一)

目录 1 70. 爬楼梯 1.1 基本思路 1.2 官方题解 2 118. 杨辉三角 3 198. 打家劫舍 菜鸟做题,语言是 C 1 70. 爬楼梯 核心思想:把总问题拆解为若干子问题。 总问题:上到 5 楼的方式有多少种子问题:上到 4 楼的方式有多…

焦虑研究的实验设备——大小鼠高架十字迷宫KT-0856

高架十字迷宫是一种广泛应用于焦虑研究的实验设备,尤其适用于啮齿类动物如大鼠和小鼠。这种迷宫的设计基于啮齿类动物的自然探究行为,以及它们对于高悬敞开环境的恐惧。通过观察和量化动物在开臂和闭臂之间的行为选择,研究人员可以评估其焦虑…

逻辑回归(Logistic Regression)详解

逻辑回归(Logistic Regression)是一种常用的统计学习方法,用于解决二分类问题。虽然名字中包含“回归”,但逻辑回归实际上是一种分类算法,而不是回归算法。它的基本原理是使用逻辑函数(也称为Sigmoid函数&a…

mysyl索引

图中一共分了三个部分: Index Key :MySQL是用来确定扫描的数据范围,实际就是可以利用到的MySQL索引部分,体现在Key Length。 Index Filter:MySQL用来确定哪些数据是可以用索引去过滤,在启用ICP后&#xff…

6、Cocos Creator 2D 渲染组件:​Sprite 组件​

Sprite 组件 Sprite(精灵)是 2D/3D 游戏最常见的显示图像的方式,在节点上添加 Sprite 组件,就可以在场景中显示项目资源中的图片。 属性功能说明Type渲染模式,包括普通(Simple)、九宫格&#x…

[C++]使用OpenCV去除面积较小的连通域

这是后期补充的部分&#xff0c;和前期的代码不太一样 效果图 源代码 //测试 void CCutImageVS2013Dlg::OnBnClickedTestButton1() {vector<vector<Point> > contours; //轮廓数组vector<Point2d> centers; //轮廓质心坐标 vector<vector<Point&…

深度学习理论基础(五)卷积神经网络CNN

目录 前述&#xff1a;卷积神经网络基础1.卷积网络流程2.卷积网络核心3.卷积下采样4.卷积上采样--转置卷积 一、卷积神经网络层1.卷积层&#xff08;1&#xff09;内部参数&#xff1a;卷积核权重&#xff08;2&#xff09;内部参数&#xff1a;偏置&#xff08;3&#xff09;外…

网络安全 | 什么是DDoS攻击?

关注WX&#xff1a;CodingTechWork DDoS-介绍 DoS&#xff1a;Denial of Service&#xff0c;拒绝服务。DDoS是通过大规模的网络流量使得正常流量不能访问受害者目标&#xff0c;是一种压垮性的网络攻击&#xff0c;而不是一种入侵手段。NTP网络时间协议&#xff0c;设备需要…

Kaggle:收入分类

先看一下数据的统计信息 import pandas as pd # 加载数据&#xff08;保留原路径&#xff0c;但在实际应用中建议使用相对路径或环境变量&#xff09; data pd.read_csv(r"C:\Users\11794\Desktop\收入分类\training.csv", encodingutf-8, encoding_errorsrepl…

HTML - 请你谈一谈img标签图片和background背景图片的区别

难度级别&#xff1a;中级及以上 提问概率&#xff1a;65% 面试官当然不会问如何使用img标签或者background来加载一张图片&#xff0c;这些知识点都很基础&#xff0c;相信只要从事前端开发一小段时间以后&#xff0c;就可以轻松搞定加载图片…

MFC通用静态库制作与使用

开发环境VS2013 1、新建工程&#xff0c;选择Win32 Project&#xff0c;命名&#xff0c;选择路径等 2、选择Static library &#xff0c;勾选MFC 3、点击完成。在工程中添加相应的头文件、源文件等通用功能函数或者类。 4、在其他工程引入使用。在使用的工程项目设置中Linker…

HarmonyOS 应用开发之通过数据管理服务实现数据共享静默访问

场景介绍 典型跨应用访问数据的用户场景下&#xff0c;数据提供方会存在多次被拉起的情况。 为了降低数据提供方拉起次数&#xff0c;提高访问速度&#xff0c;OpenHarmony提供了一种不拉起数据提供方直接访问数据库的方式&#xff0c;即静默数据访问。 静默数据访问通过数据…

基于Python+Tkinter实现一个贪食蛇小游戏

你是否还记得那个时代&#xff0c;当我们的手机还没有触摸屏&#xff0c;游戏也只有像“贪食蛇”这样的经典款&#xff1f;当时&#xff0c;许多人都沉迷于控制一条小蛇吃食物的乐趣中。而今&#xff0c;让我们利用Python和Tkinter&#xff0c;一起重温那个时代&#xff0c;制作…

程序汪10万接的多平台视频分发项目,模拟人工发视频

本项目来自程序汪背后的私活小团队&#xff0c;开发了一个多平台分发视频项目&#xff0c;给粉丝分享一下解决方案和具体项目分开情况付款情况等等细节&#xff0c;希望给想接私活的朋友一些经验参考 程序汪10万接的多平台视频分发项目&#xff0c;模拟人工发视频 视频版本 在 …

LabVIEW挖坑指南

一、挖坑指南 1.1、输出变量放在条件框内 错误写法&#xff1a; 现象&#xff1a;如果没进入对应的分支&#xff0c;输出为默认值 正常写法&#xff1a; 让每个分支输出的值都在预料之内。 1.2、统计耗时不准 错误写法 现象&#xff1a;统计出来的耗时是2000ms 正常写法&a…

redis发布订阅模式

需要两个终端。 首先我们打开第一个终端&#xff0c;使用SUBSCRIBE命令来订阅一个频道。 打开另一个终端&#xff0c;发布信息使用PUBLISH&#xff0c;后面加上频道的名称和消息的内容 返回去看第一个终端 订阅频道的终端可以有多个。但是订阅频道有一些局限性&#xff0c;比如…

【web】nginx+php-fpm云导航项目部署-(简版)

一、yum安装nginx yum -y install nginx 二、php环境安装 2.1 php安装 yum -y install php 2.2 php-fpm安装 yum -y install php-fpm 注&#xff1a;PHP在 5.3.3 之后已经讲php-fpm写入php源码核心了。 2.3 项目依赖的php-xml和php-xmlrpc安装 yum -y install php-…