Vue 3 的响应式原理

news2025/4/14 21:16:27

Vue 3 的响应式原理可以比喻为“智能监控系统”:当数据变化时,它能自动追踪依赖关系并触发更新。以下是通俗解释和核心机制:


一、核心原理:Proxy 代理

Vue 3 的响应式系统基于 JavaScript 的 Proxy 对象实现(Vue 2 使用 Object.defineProperty)。
Proxy 的优势

  • 支持动态新增属性(无需 Vue.set
  • 支持数组索引和长度变化
  • 性能更好(无需递归遍历对象)

二、实现步骤:如何让数据“活”起来?

1. 创建响应式对象

reactive() 包裹普通对象,返回一个 Proxy 代理对象:

import { reactive } from 'vue';

const state = reactive({
  count: 0,
  list: ['Apple', 'Banana']
});

Proxy 的拦截行为

  • 当你访问 state.countget 操作)→ 收集依赖(记录谁在用这个值)。
  • 当你修改 state.countset 操作)→ 触发更新(通知依赖它的地方更新)。

2. 依赖收集(Tracking Dependencies)

当模板或计算属性访问响应式数据时,Vue 会记录这个关系:

<template>
  <div>{{ state.count }}</div>  <!-- 访问 state.count → 建立依赖 -->
</template>

原理

  • 通过 effect 函数(类似“监听器”)包裹需要响应式执行的代码。
  • 当代码执行时,所有被访问的响应式属性会自动收集当前 effect 作为依赖。

3. 触发更新(Triggering Updates)

当数据变化时,Proxy 的 set 拦截器会找到所有关联的 effect 并重新执行它们:

state.count = 10; // 触发 set → 通知所有依赖的 effect 更新

三、核心 API 的差异

1. reactive vs ref
  • reactive:针对对象(Object、Array)的深度代理。

    const obj = reactive({ a: 1 });
    
  • ref:针对基本类型(string、number、boolean),通过 .value 访问。

    const count = ref(0);
    console.log(count.value); // 0
    

    为什么需要 ref
    Proxy 无法直接代理基本类型,ref 将值包装在 { value: ... } 对象中,再对这个对象做响应式处理。


2. effect 函数

Vue 内部通过 effect 实现依赖追踪和更新触发(开发者通常通过 watchcomputed 间接使用):

import { effect } from 'vue';

effect(() => {
  console.log('count变化了:', state.count); // 自动追踪 state.count
});

四、简单实现(极简版)

// 极简响应式系统
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key); // 收集依赖
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      trigger(target, key); // 触发更新
      return true;
    }
  });
}

// 依赖收集和触发
let activeEffect = null;
const depsMap = new Map();

function track(target, key) {
  if (activeEffect) {
    let dep = depsMap.get(target)?.get(key);
    if (!dep) {
      dep = new Set();
      depsMap.set(target, (depsMap.get(target) || new Map()).set(key, dep));
    }
    dep.add(activeEffect);
  }
}

function trigger(target, key) {
  const dep = depsMap.get(target)?.get(key);
  dep?.forEach(effect => effect());
}

function effect(fn) {
  activeEffect = fn;
  fn(); // 首次执行以收集依赖
  activeEffect = null;
}

五、关键特点

  1. 嵌套对象自动代理
    reactive 会递归代理对象的所有嵌套属性。

  2. 懒代理
    Vue 3 不会立即代理所有属性,只有被访问到的属性才会被代理(性能优化)。

  3. 数组处理优化
    直接通过索引修改数组或修改 length 属性也能触发更新。


六、开发者注意事项

  1. 避免解构响应式对象
    解构会破坏代理关系,导致失去响应性:

    const { count } = state; // ❌ 错误!count 不再是响应式的
    const count = ref(state.count); // ✅ 正确
    
  2. 使用 toRefs 保持响应性
    解构时保持响应式:

    import { toRefs } from 'vue';
    const { count } = toRefs(state); // 通过 .value 访问
    

七、总结

Vue 3 的响应式系统像一个“智能摄像头”:

  1. 监控数据访问get):记录谁在关注这个数据。
  2. 监控数据修改set):通知所有关注者更新。
  3. 自动化管理依赖:开发者只需关注数据变化,视图自动同步。

通过 Proxy 的强大能力,Vue 3 解决了 Vue 2 的诸多限制(如数组和新增属性的响应问题),同时提升了性能和开发体验。

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

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

相关文章

【JS】使用滑动窗口得到无重复字符的最长子串

题目 思路 本题采用滑动窗口思想&#xff0c;定义左右指针作为滑动窗口的边界&#xff0c;使用Set数据结构处理重复字符&#xff0c;需要注意的是&#xff1a;每次遍历时采用Math.max方法实时更新最长子串的长度&#xff1b;当左指针移动时&#xff0c;set要删除对应字符。 步…

2025-04-05 吴恩达机器学习4——逻辑回归(1):基础入门

文章目录 1 分类问题1.1 介绍1.2 线性回归与分类1.2 逻辑回归 2 逻辑回归2.1 介绍2.2 Sigmoid 函数2.3 逻辑回归模型 3 决策边界3.1 概念3.2 线性决策边界3.3 非线性决策边界 4 代价函数4.1 不使用平方误差4.2 损失函数4.3 整体代价函数 5 梯度下降5.1 参数更新5.2 逻辑回归 vs…

P1125 [NOIP 2008 提高组] 笨小猴

#include<bits/stdc.h> using namespace std; int a[300],ma,mi105;//数组用来记录每个字符出现的次数&#xff0c;将mi初始为一个比较大的值 bool is_prime(int x){if(x0||x1)return false;for(int i2;i*i<x;i){if(x%i0)return false;}return true; }//判断是否为质…

Linux systemd 服务全面详解

一、systemd 是什么&#xff1f; systemd 是 Linux 系统的现代初始化系统&#xff08;init&#xff09;和服务管理器&#xff0c;替代传统的 SysVinit 和 Upstart。它不仅是系统启动的“总指挥”&#xff0c;还统一管理服务、日志、设备挂载、定时任务等。 核心作用 服务管理…

SortedSet结构之用户积分实时榜单实战

Redis 中的SortedSet结构非常适合用于实现实时榜单的场景&#xff0c;它根据成员的分数自动进行排序&#xff0c;支持高效的添加、更新和查询操作。 SortedSet实时榜单的一些典型应用场景&#xff1a; 游戏中的玩家排行榜&#xff1a;在多人在线游戏中&#xff0c;使用 Sorte…

C++_类和对象(中)

【本节目标】 类的6个默认成员函数构造函数析构函数拷贝构造函数赋值运算符重载const成员函数取地址及const取地址操作符重载 1. 类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什…

学习笔记—C++—入门基础()

目录 C介绍 参考文档 C第一个程序 命名空间namespace namespace的价值 namespace的定义 namespace使用 指定命名空间访问 using将命名空间中某个成员展开 展开命名空间中全部成员 输入和输出 缺省参数 函数重载 引用 引用的概念 应用 const引用 指针和引用的关…

大数据Spark(五十七):Spark运行架构与MapReduce区别

文章目录 Spark运行架构与MapReduce区别 一、Spark运行架构 二、Spark与MapReduce区别 Spark运行架构与MapReduce区别 一、Spark运行架构 Master:Spark集群中资源管理主节点&#xff0c;负责管理Worker节点。Worker:Spark集群中资源管理的从节点&#xff0c;负责任务的运行…

道路裂缝数据集CrackForest-156-labelme

来源于开源的数据集 https://github.com/cuilimeng/CrackForest-dataset 进行整理修改而成。 文章目录 1. 介绍2. 应用场景3. 相关工具4. 下载地址 1. 介绍 在现代城市管理中&#xff0c;道路状况的监测与维护是确保交通安全和城市基础设施健康的重要环节。 CrackForest是一个…

Redis数据结构之Hash

目录 1.概述2.常见操作2.1 H(M)SET/H(M)GET2.2 HGETALL2.3 HDEL2.4 HLEN2.5 HEXISTS2.6 HKEYS/HVALS2.7 HINCRBY2.8 HSETNX 3.总结 1.概述 Hash是一个String类型的field(字段)和value(值)的映射表&#xff0c;而且value是一个键值对集合&#xff0c;类似Map<String, Map<…

故障矩阵像素照片效果ps标题文本特效滤镜样机 Glitched Arcade Text Logo Effect

有时&#xff0c;视觉效果比文字本身更能讲述故事&#xff0c;因此请确保您已竭尽全力提供令人敬畏的展示。品牌标识或演示元素&#xff0c;该资产可以处理您的项目所涉及的任何内容。由于智能对象图层&#xff0c;此文本效果将为获得理想的结果铺平道路。这些允许您在指定的图…

[创业之路-352]:从创业和公司经营的角度看:分析美国的三大财务报表

一、美国政府的财务报表 如果把美国政府看成一个公司&#xff0c;从三大财务报表上看&#xff0c;美国政府资产雄厚&#xff0c;但利润表年年亏损&#xff0c;现金流量表年年为负&#xff0c;现金流持续吃紧&#xff0c;面临现金流断裂导致公司倒闭的风险。 马斯克在降低公司各…

【教学类-102-02】自制剪纸图案(留白边、沿线剪)02——Python+PS自动化添加虚线边框

背景需求: 01版本实现了对透明背景png图案边界线的扩展,黑线实线描边 【教学类-102-01】自制剪纸图案(留白边、沿线剪)01-CSDN博客文章浏览阅读974次,点赞15次,收藏7次。【教学类-102-01】自制剪纸图案(留白边、沿线剪)01https://blog.csdn.net/reasonsummer/article…

OFP--2018

文章目录 AbstractIntroductionRelated Work2D object detection3D object detection from LiDAR3D object detection from imagesIntegral images 3D Object Detection ArchitectureFeature extractionOrthographic feature transformFast average pooling with integral imag…

CentOS-查询实时报错日志-查询前1天业务报错gz压缩日志

最新版本更新 https://code.jiangjiesheng.cn/article/364?fromcsdn 推荐 《高并发 & 微服务 & 性能调优实战案例100讲 源码下载》 1. 查询实时报错日志 物理路径&#xff08;带*的放在靠后&#xff0c;或者不用*&#xff09; cd /home/logs/java-gz-log-dir &am…

ETF 场内基金是什么?佣金最低又是多少呢?

嘿&#xff0c;朋友们&#xff0c;大家好啊&#xff0c;我是StockMasterX&#xff0c;今天咱们就坐下来慢慢聊聊这个话题&#xff0c;ETF 场内基金到底是个啥东西&#xff0c;它的佣金最低能到多少&#xff0c;真的是个值得深挖的问题。 说起ETF&#xff0c;我还记得刚入行那会…

[论文阅读]PMC-LLaMA: Towards Building Open-source Language Models for Medicine

PMC-LLaMA&#xff1a;构建医学开源语言模型 摘要 最近&#xff0c;大语言模型在自然语言理解方面展现了非凡的能力。尽管在日常交流和问答场景下表现很好&#xff0c;但是由于缺乏特定领域的知识&#xff0c;这些模型在需要精确度的领域经常表现不佳&#xff0c;例如医学应用…

26考研——线性表(2)

408答疑 文章目录 一、线性表的定义和基本操作二、线性表的顺序表示三、 线性表的链式表示四、 顺序表和链表的比较五、参考资料鲍鱼科技课件26王道考研书 六、总结顺序表总结顺序表特点深入掌握顺序表的管理方式 单链表总结双循环链表总结 一、线性表的定义和基本操作 文章链…

低代码开发平台:飞帆画 echarts 柱状图

https://fvi.cn/711 柱状图这个控件是由折线图的控件改过来的&#xff0c;在配置中&#xff0c;单选框选择柱状图就行了。

PowerPhotos:拯救你的Mac照片库,告别苹果原生应用的局限

如果你用Mac管理照片&#xff0c;大概率被苹果原生「照片」应用折磨过——无法真正并行操作多个图库。每次切换图库都要关闭重启&#xff0c;想合并照片得手动导出导入&#xff0c;重复文件更是无处可逃…… 直到我发现了 PowerPhotos&#xff0c;这款专为Mac设计的照片库管理…