Vue2中为啥不用 Object.defineProperty 实现响应式数组 ? 不能监听到数组变化吗?

Vue2.0 对于数据响应式的实现上是有一些局限性的,比如:

  1. 无法检测数组和对象的新增;
  2. 无法检测通过索引改变数组的操作;

针对以上问题,我们一般都会把锅甩给 Object.defineProperty。所以,在Vue 3.0 中,尤大把响应式数据部分弃用了 Object.defineProperty,而使用 Proxy 来代替它。

难道 Object.defineProperty 真的要背这锅么,下面就来分析一下 Object.defineProperty 真的无法监测数组下标的变化吗?

先说结论:

首先,Object.defineProperty 本身是可以监控到数组下标的变化的,只是在 Vue 的实现中,从性能/体验的性价比考虑,便放弃了这个特性。

Object.defineProperty 无法直接监听数组的变化。这是因为 Object.defineProperty 可以拦截对象属性的读取和写入操作,但无法拦截数组的方法调用(如 pushpopshiftunshiftsplicesortreverse)。具体来说,Object.defineProperty 可以监听数组的元素的增加和修改,但不能监听数组长度的变化和数组方法的调用

function defineReactive(data, key, value) {
	 Object.defineProperty(data, key, {
		 enumerable: true,
		 configurable: true,
		 get: function defineGet() {
			 console.log(`get key: ${key} value: ${value}`)
			 return value
		 },
		 set: function defineSet(newVal) {
			 console.log(`set key: ${key} value: ${newVal}`)
			 value = newVal
		 }
	 })
}
 
function observe(data) {
	Object.keys(data).forEach(function(key) {
		defineReactive(data, key, data[key])
	})
}
 
let arr = [1, 2, 3]
observe(arr)

从以上操作的结果,可以看出:我们通过索引改变 arr[1],可以发现触发了 set,也就是Object.defineProperty 是可以检测到通过索引改变数组的操作的。

但是有一个问题,就是对于数组的一些常用方法如push/pop等,无法触发监听;

Vue 2 对数组的响应式处理
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);

['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => {
  const original = arrayProto[method];
  Object.defineProperty(arrayMethods, method, {
    value: function mutator(...args) {
      const result = original.apply(this, args);
      // 触发视图更新逻辑
      console.log(`Array method ${method} called`);
      return result;
    },
    enumerable: false,
    writable: true,
    configurable: true
  });
});

function observeArray(arr) {
  arr.__proto__ = arrayMethods;
}

let arr = [];
observeArray(arr);
arr.push(1);  // 会触发自定义的 push 方法
那vue2中如何处理新增的属性和删除的属性 ? 实现原理是什么?

Vue 2 提供了 Vue.set 方法来处理新增属性,使新增的属性能够被响应式系统检测到。

实现原理
  1. 检测对象:首先,Vue.set 会检查目标是否是一个对象。
  2. 针对数组:使用 splice使用 splice 方法在特定位置插入新元素,从而触发数组的响应式更新。
  3. 针对对象:递归响应化:接着会递归地使新增属性响应化,即调用内部的 defineReactive 方法。
  4. 触发依赖更新:最后,手动触发对象的依赖更新,使得视图能够响应变化。

Vue 2 提供了 Vue.delete 方法来处理属性删除,使得删除的属性能够触发视图更新。

实现原理
  1. 检测对象:首先,Vue.delete 会检查目标是否是一个对象。
  2. 删除属性:删除目标对象上的指定属性。
  3. 触发依赖更新:手动触发对象的依赖更新,使得视图能够响应变化。

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

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

相关文章

uniapp 小程序 堆叠轮播图 左滑 右滑 自动翻页 点击停止自动翻页

uniapp 小程序 堆叠轮播图 左滑 右滑 自动翻页 点击停止自动翻页 超过指定时间未点击滑动 则继续开始滚动 直接上代码 componentSwiper.vue 需要注意页面切换时清除计时器 <template><view><view class"swiperPanel" touchstart"startMove"…

STM32烧写hex及bin文件的五种方法

一.STVP 1.概述 STVP是ST早期的一款下载编程工具&#xff0c;支持早期的ST早期的芯片&#xff08;比如ST7系列&#xff09;&#xff0c;也支持STM8、 STM32。 该工具虽然相对ST-LINK utility、STM32CubeProg比较老&#xff0c;但该工具官方在2017年还进行了维护&#xff0c;现…

基于web的摩托车销售系统的设计与实现-计算机毕业设计源码031706

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对摩托车销售系统等问题&#xff0c;对摩托车…

<sa8650>QCX Usecase 使用详解— Spectra Studio工程建立

<sa8650>QCX Usecase 使用详解— Spectra Studio工程建立 一 前言二 建立usecase工程2.1 前提2.2 创建usecase工程3.2 查看usecase2三 总结一 前言 目前高通平台在camera模块中,我们会使用到usecase这么一个功能模块;本文主要讲解sa8650平台中,通过Spectra Studio 可视化…

[C/C++][VsCode]使用VsCode在Linux上开发和Vscode在线调试

目录 0. 前言1. win10上搭建环境Linux环境2.编写makefile3.怎么在线调试结语 0. 前言 在开发中&#xff0c;可以一边开发一边调试&#xff0c;这样可以大大的减少bug&#xff1b;但是正常来说一个大点的项目&#xff0c;是不太可能单步调试的&#xff0c;因为一般都是用make或…

无人机螺旋桨理论教学培训课程

本文档为一份详细的关于TYTO机器人公司提供的电机和螺旋桨理论及其实验操作的指南。指南首先概述了材料、实验目标以及实验的介绍部分&#xff0c;随后详细阐述了理论问题、实验步骤和附录内容。实验目的在于通过实际测试来测量和理解不同螺旋桨参数对无人机性能的影响&#xf…

手把手教你使用kimi创建流程图【实践篇】

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 引言 在昨日的文章中&#xff0c;我们介绍了如何使用Kimi生成论文中的流程图。今天&#xff0c;我们将更进一步&#xff0c;通过实践案例来展示Kimi在生成流程图方面的应用。这不仅将加…

回归洛伦兹变换

现在再回到洛伦兹变换&#xff0c; 将其写成上角标表示惯性系的形式&#xff08;注意不是幂次&#xff09;&#xff0c; 并且认为洛伦兹变换中的两个方程的比例常数&#xff0c; 并不仅仅是因为虚数单位数量巨大导致的“误判”&#xff0c;虽然这也是说得通的。因为我们已经看到…

Python 爬虫从入门到入狱之路一

实际上爬虫一共就四个主要步骤&#xff1a; 明确目标 (要知道你准备在哪个范围或者网站去搜索)爬 (将所有的网站的内容全部爬下来)取 (去掉对我们没用处的数据)处理数据&#xff08;按照我们想要的方式存储和使用&#xff09; 我们在之前写的爬虫程序中&#xff0c;都只是获取…

通讯:单片机串口和电脑通讯

目录 1.串口输出数据到电脑 硬件部分 串口输出数据到电脑的软件软件部分&#xff1a; 相关问题&#xff1a; 2.单片机串口--485--485转USB--电脑 串口&#xff0c;芯片&#xff0c;转换器&#xff0c;设备之间的通讯的接线&#xff0c;都是要TX--RX, RX--TX 交叉连接。 单…

基于springboot+Vue高校宿舍管理系统的设计与实现【附源码】

本科毕业设计&#xff08;论文&#xff09; 基于springbootVue高校宿舍管理系统的设计与实现 目录 摘要 2 第一章 绪论 2 1.1 开发背景 2 1.2 开发意义 2 第二章 系统分析 3 2.1 系统的需求分析 3 2.2 系统开发设计思想 3 2.3系统开发步骤 3 2.4 系统的主要技术 4 2.4.1 B/S系…

70年,800个,全球AI大模型数据可视化;750名工程师透露的AI真相;GenAI将取代初级程序员?NO!出海美国的创始人必读手册 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;ShowMeAI官网 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; 1. Anthropic 发布 Claude Artifacts&#xff0c;大模型从「聊天」正式迈入「工作流」 上周&#xff0c;Anthropic 公司发布了最新的大模型 Claude 3.5 Sonnet&am…

2024年【山东省安全员B证】最新解析及山东省安全员B证操作证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【山东省安全员B证】最新解析及山东省安全员B证操作证考试&#xff0c;包含山东省安全员B证最新解析答案和解析及山东省安全员B证操作证考试练习。安全生产模拟考试一点通结合国家山东省安全员B证考试最新大纲及…

AI助手的超级工具箱:Phidata框架实战指南

目录 引言一、Phidata概述二、Phidata的安装与快速入门1、安装Phidata2、环境配置3、快速入门3.1 可以搜索网页的助手3.2 可以查询财务数据的助手 三、Phidata的高级应用1、可以编写和运行Python代码的助手2、可以使用 SQL 分析数据的助手3、可生成 Pydantic 模型的助手4、具有…

探索Uptime命令:Linux系统管理员的必备工具

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 探索Uptime命令&#xff1a;Linux系统管理员的必备工具 前言基本用法语法输出示例输出字段解释系…

【RF Transceiver】ADRV9040 8T8R

具有DFE、400MHz iBW射频收发器的8T8R SoC 特性 8个差分发送器&#xff08;Tx&#xff09; 8个差分接收器&#xff08;Rx&#xff09; 2个观察接收器&#xff08;ORx&#xff09; 单频段和多频段&#xff08;N x 2T2R/4T4R&#xff09;能力 可调范围1内4个波段轮廓 调谐范围&a…

记录一个笔误引发的bug导致生产环境报错,但是本地环境,测试环境运行正常

记录一个笔误引发的bug导致生产环境报错&#xff0c;但是本地环境&#xff0c;测试环境运行正常 因为headers请求头过长导致报错 在feign外调其他系统时候&#xff0c;是重新封装headers 问题在于 MultiValueMap 属于静态变量。这里讲userAgent的内容传递过去。是不断累加的…

Stable Diffusion【进阶篇】:真人漫改之迪士尼风格定制

大家好&#xff0c;我是极客菌 关于真人漫改是一个应用比较多的图片定制方向&#xff0c;本文以及后面的章节我们结合一些具体的大模型或者LORA来更深入的实践一下。 一. 迪士尼风格 在SD的大模型中&#xff0c;实现迪士尼或者皮卡斯风格的图片&#xff0c;首推 Disney Pix…

C# 任务调度 c# TaskScheduler

摘要 在C#中&#xff0c;TaskScheduler是一种非常有用的功能&#xff0c;它允许您在指定的时间或间隔内执行任务。TaskScheduler是一个抽象类&#xff0c;它提供了一个通用的方法来计划和执行任务。您可以使用TaskScheduler来调度多个任务&#xff0c;并且在多线程环境中控制它…

智能体——父亲兴趣爱好助手

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…