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.mzph.cn/bicheng/35348.shtml

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

相关文章

每天一个数据分析题(三百九十一)- 多元线性回归

在多元线性回归模型中自变量的系数矩阵X为列满秩,则表明矩阵X的列向量之间是什么关系? A. 线性相关 B. 存在多重共线性 C. 线性无关 D. 无法判断 数据分析认证考试介绍:点击进入 题目来源于CDA模拟题库 点击此处获取答案 数据分析专项…

No module named ‘cStringIO‘

No module named cStringIO 解决方法: import io as sio

Linux---- 防火墙

查看防火墙状态 systemctl status firewalld关闭防火墙 systemctl stop firewalld永久关闭防火墙 systemctl stop firewalld systemctl disable firewalld打开防火墙 systemctl start firewalld查看所有已开放的临时端口 firewall-cmd --list-ports查看所有永久开放的端口…

基于Java微信小程序民宿短租系统设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟感兴趣的可以先收藏起来,还…

Mongodb地理信息数据查询

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第78篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关…

K8s部署一个nginx的应用

我们在mster节点上主要有两种部署应用的方式,一个是通过命令行的形式,一个是通过编写yaml文件的形式,类似linux中脚本一样。以下是部署nginx的例子: 一、通过命令行的方式 : 1、部署应用kubectl create deployment ngi…

IDEA中使用leetcode 刷题

目录 1.IDEA下载leetcode插件 2.侧边点开插件 3.打开网页版登录找到cookie复制 4.回到IDEA登录 5.刷题 6.共勉 1.IDEA下载leetcode插件 2.侧边点开插件 3.打开网页版登录找到cookie复制 4.回到IDEA登录 5.刷题 6.共勉 算法题来了不畏惧, 挑战前行是成长的舞台…

qmt量化交易策略小白学习笔记第51期【qmt编程之期货列表--国债期货合约表】

qmt编程之获取期货列表 qmt更加详细的教程方法,会持续慢慢梳理。 也可找寻博主的历史文章,搜索关键词查看解决方案 ! 期货列表 #金融期货列表 提供当前时间段内有效的金融期货合约数据(如行情数据等),…

AI实战案例!如何运用SD完成运营设计海报?玩转Stable Diffusion必知的3大绝技

大家好我是安琪! Satble Diffusion 给视觉设计带来了前所未有的可能性和机会,它为设计师提供了更多选择和工具的同时,也改变了设计师的角色和设计流程。然而,设计师与人工智能软件的协作和创新能力仍然是不可或缺的。接下来我将从…

【LinuxC语言】UDP数据收发

文章目录 前言udp流程图udp函数介绍bind函数recvfrom函数sendto函数示例代码总结前言 在计算机网络中,UDP(用户数据报协议)是一种无连接的传输层协议,它允许应用程序快速地发送短的消息或数据报。由于UDP不需要建立和断开连接,因此它的传输速度往往比其他协议更快,但它也…

EfficientNet-V2论文阅读笔记

目录 EfficientNetV2: Smaller Models and Faster Training摘要Introduction—简介Related work—相关工作EfficientNetV2 Architecture Design—高效EfficientNetV2架构设计Understanding Training Efficiency—了解训练效率Training-Aware NAS and Scaling—训练感知NAS和缩放…

1、Python编程入门:从硬件基础到解释器类型

Python是一种免费、开源、跨平台、动态、面向对象的编程语言。它以其简洁易读的语法和强大的功能而闻名,广泛应用于各种领域,如Web开发、数据分析、人工智能等。本文将介绍Python的基本概念、执行方式以及常用的Linux命令,帮助初学者快速入门…

DHT11

第一个传感----DHT11 通过前面的学习,你已经学会了控制IO口、延时函数、串口的收发。接下来,你就可以借助以上的知识点完成自己的第一个传感器--DHT11啦! DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。应用非常广…

【ai】tx2 nx : fix pip升级警告

jetson 环境同样出现:【原创】pip3 使用报警问题在对 Ubuntu 18.04 上的 pip3 9.0.1 版本使用 pip install -U pip 的方式进行升级后,再使用 pip 就会出现一堆警告信息。这个警告信息目前不影响使用,但从警告信息来看,会在未来版本中出现失败风险。 当前系统中存在了两个不…

【浅学】大模型(科普向_持续更新中)

【读者福利】大模型全套教程,微信扫码领取~ 1. 大模型概述 大模型是指具有数千万甚至数亿参数的深度学习模型。 当我们提及大模型时,通常指的是大语言模型(Large Language Model,简称LLM),即文字问答模型…

RAID详解及配置实战

目录 一、RAID磁盘阵列及详解 1.1 了解RAID 1.1.1 简单理解 1.1.2 对比了解 1.2 RAID磁盘阵列介绍 1.3 RAID功能实现 1.4 RAID实现的方式 1.5 RAID级别详解 1.5.1 RAID -0 1.5.2 RAID -1 1.5.3 RAID -5 1.5.4 RAID -10(RAID 10) 1.6 阵列卡…

Vue的组件通信

前言 今天讲讲Vue的组件通信的几种方式 正文 父子通讯 – 父给子 父组件将值 v-bind 绑定传给子组件,子组件通过 degineProps 接收 接下来用一个代码示例讲解一下 父组件 value 是使用 ref 创建的响应式变量,用于绑定输入框的值。to 也是使用 ref 创…

AI推介-多模态视觉语言模型VLMs论文速览(arXiv方向):2024.06.10-2024.06.15

文章目录~ 1.MIND: Multimodal Shopping Intention Distillation from Large Vision-language Models for E-commerce Purchase Understanding2.MDA: An Interpretable Multi-Modal Fusion with Missing Modalities and Intrinsic Noise3.VEGA: Learning Interleaved Image-Tex…

数据驭王: PostgreSQL教程指南解密

PostgreSQL教程大纲 一、介绍1.1 什么是PostgreSQL?1.2 PostgreSQL的历史和发展1.3 为什么选择PostgreSQL? 二、安装和设置2.1 下载和安装PostgreSQL2.2 配置PostgreSQL2.3 测试PostgreSQL 三、基本操作3.1 连接到PostgreSQL数据库步骤一:安装…

如何实现灌区闸门控制自动化?宏电“灌区哨兵”为灌区闸门控制添“智慧”动能

闸门控制站是节水灌溉工程中的重要组成部分。随着科技的不断进步和农田水利现代化的发展,传统的闸门控制和管理手段已经不能满足现代农业的发展要求。以宏电“灌区哨兵”为核心的闸门自动化控制系统,能有效解决灌区闸门距离远、数量多、不易操作、不好监…