iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > node.js >Vue不能检测数组变动的原因是什么
  • 451
分享到

Vue不能检测数组变动的原因是什么

2024-04-02 19:04:59 451人浏览 独家记忆
摘要

小编给大家分享一下Vue不能检测数组变动的原因是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!问题来源:https://se

小编给大家分享一下Vue不能检测数组变动的原因是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

问题来源:https://segmentfault.com/q/1010000015780995

问题描述:Vue检测数据的变动是通过Object.defineProperty实现的,所以无法监听数组的添加操作是可以理解的,因为是在构造函数中就已经为所有属性做了这个检测绑定操作。

但是官方的原文:由于 javascript 的限制, Vue 不能检测以下变动的数组:

当你利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如: vm.items.length = newLength

这句话是什么意思?我测试了下Object.defineProperty是可以通过索引属性来设置属性的访问器属性的,那为何做不了监听?

有些论坛上的人说因为数组长度是可变的,即使长度为5,但是未必有索引4,我就想问问这个答案哪里来的,修改length,新增的元素会被添加到最后,它的值为undefined,通过索引一样可以获取他们的值,怎么就叫做“未必有索引4”了呢?

既然知道数组的长度为何不能遍历所有元素并通过索引这个属性全部添加set和get不就可以同时更新视图了吗?

如果非要说的话,考虑到性能的问题,假设元素内容只有4个有意义的值,但是长度确实1000,我们不可能为1000个元素做检测操作。但是官方说的由于js限制,我想知道这个限制是什么内容?各位大大帮我解决下这个问题,感谢万分

面对这个问题,我想说的是,首先,长度为1000,但只有4个元素的数组并不一定会影响性能,因为js中对数据的遍历除了for循环还有forEach、map、filter、some等,除了for循环外(for,for...of),其他的遍历都是对键值的遍历,也就是除了那四个元素外的空位并不会进行遍历(执行回调),所以也就不会造成性能损耗,因为循环体中没有操作的话,所带来的性能影响可以忽略不计,下面是长度为10000,但只有两个元素的数组分别使用for及forEach遍历的结果:

var arr = [1]; arr[10000] = 1
function a(){
  console.time()
  for(var i = 0;i<arr.length;i++)console.log(1)
  console.timeEnd()
}
a(); //default: 567.1669921875ms
a(); //default: 566.2451171875ms

function b(){
  console.time()
  arr.forEach(item=>{console.log(2)})
  console.timeEnd()
}
b(); //default: 0.81982421875ms
b(); //default: 0.434814453125ms

可以看到结果非常明显,不过,如果for循环中不做操作的话两者速度差不多

其次,我要说的是,我也不知道这个限制是什么 (⇀‸↼‶) ╮( •́ω•̀ )╭

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。数组的索引也是属性,所以我们是可以监听到数组元素的变化的

var arr = [1,2,3,4]
arr.forEach((item,index)=>{
  Object.defineProperty(arr,index,{
    set:function(val){
      console.log('set')
      item = val
    },
    get:function(val){
      console.log('get')
      return item
    }
  })
})
arr[1]; // get 2
arr[1] = 1; // set 1

但是我们新增一个元素,就不会触发监听事件,因为这个新属性我们并没有监听,删除一个属性也是。

再回到题主的问题,既然数组是可以被监听的,那为什么vue不能检测vm.items[indexOfItem] = newValue导致的数组元素改变呢,哪怕这个下标所对应的元素是存在的,且被监听了的?

为了搞清楚这个问题,我用vue的源码测试了下,下面是vue对数据监测的源码:

Vue不能检测数组变动的原因是什么

可以看到,当数据是数组时,会停止对数据属性的监测,我们修改一下源码:

Vue不能检测数组变动的原因是什么

使数据为数组时,依然监测其属性,然后在defineReactive函数中的get,set打印一些东西,方便我们知道调用了get以及set。这里加了个简单判断,只看数组元素的get,set

Vue不能检测数组变动的原因是什么

然后写了一个简单案例,主要测试使用vm.items[indexOfItem] = newValue改变数组元素能不能被监测到,并响应式的渲染页面

Vue不能检测数组变动的原因是什么

运行页面

Vue不能检测数组变动的原因是什么

可以看到,运行了6次get,我们数组长度为3,也就是说数组被遍历了两遍。两遍不多,页面渲染一次,可能多次触发一个数据的监听事件,哪怕这个数据只用了一次,具体的需要看尤大代码怎么写的。就拿这个来说,当监听的数据为数组时,会运行dependArray函数(代码在上面图中get的实现里),这个函数里对数组进行了遍历取值操作,所以会多3遍get,这里主要是vue对data中arr数组的监听触发了dependArray函数。

当我们点击其中一个元素的时候,比如我点击的是3

Vue不能检测数组变动的原因是什么

可以看到会先运行一次set,然后数据更新,重新渲染页面,数组又是被遍历了两遍。

但是!!!数组确实变成响应式的了,也就是说js语法功能并不会限制数组的监测。

这里我们是用长度为3的数组测试的,当我把数组长度增加到9时

Vue不能检测数组变动的原因是什么

可以看到,运行了18次get,数组还是被遍历了两遍,点击某个元素同理,渲染的时候也是被遍历两次。

Vue不能检测数组变动的原因是什么

有了上面的实验,我的结论是数组在vue中是可以实现响应式更新的,但是不明白尤大是出于什么考虑,没有加入这一功能,希望有知道的大佬们不吝赐教

2018-07-27补充

GitHub上提问了尤大

Vue不能检测数组变动的原因是什么

以上是“Vue不能检测数组变动的原因是什么”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网node.js频道!

--结束END--

本文标题: Vue不能检测数组变动的原因是什么

本文链接: https://www.lsjlt.com/news/73381.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue不能检测数组变动的原因是什么
    小编给大家分享一下Vue不能检测数组变动的原因是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!问题来源:https://se...
    99+
    2024-04-02
  • Vue2中无法检测到数组变动的原因及解决
    目录解决方法为什么Vue2.0中监听不到两种数组的变化? 源码分析 Vue3.0 由于JavaScript 的限制,Vue 不能检测以下数组的变动: 当利用索引直接设置一个...
    99+
    2024-04-02
  • 如何解决Vue不能检测数组或对象变动的问题
    小编给大家分享一下如何解决Vue不能检测数组或对象变动的问题,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!来看一个实例:<!DOCTYPE html> <htm...
    99+
    2024-04-02
  • vue中是如何检测数组变化的
    vue中检测数组变化的方法:vue使用函数劫持的方式,通过重写数组的某些方法来检测数组变化。在将数组处理成响应式数据后,如果使用数组原始方法改变数组时,数组值会发生变化,但是并不会触发数组的setter来通知所有依赖该数组的地方进行更新,若...
    99+
    2024-04-02
  • Vue无法检测到数组变动怎么解决
    这篇“Vue无法检测到数组变动怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue无法检测到数组变动怎么解决”文章吧...
    99+
    2023-07-04
  • vue如何检测对象和数组的变化
    这篇文章主要介绍了vue如何检测对象和数组的变化的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vue如何检测对象和数组的变化文章都会有所收获,下面我们一起来看看吧。检测对象变化1、不能检测到对象属性的添加或删除...
    99+
    2023-07-04
  • vue中watch和computed能监听到数据改变的原因是什么
    这篇文章主要为大家展示了“vue中watch和computed能监听到数据改变的原因是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue中watch和co...
    99+
    2024-04-02
  • Oracle Listener服务不能启动的原因是什么
    这篇文章给大家介绍Oracle Listener服务不能启动的原因是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。    最近时间,更换了项目组,最近...
    99+
    2024-04-02
  • swoole不能用sleep的原因是什么
    这篇文章主要介绍“swoole不能用sleep的原因是什么”,在日常操作中,相信很多人在swoole不能用sleep的原因是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”swoole不能用sleep的原因...
    99+
    2023-06-30
  • redis整数集不能降级的原因是什么
    这篇文章主要为大家展示了“redis整数集不能降级的原因是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“redis整数集不能降级的原因是什么”这篇文章吧。基...
    99+
    2024-04-02
  • ChatGPT不能访问是什么原因
    ChatGPT不能访问的原因有:1、网络连接不稳定,出现chatGPTisatcapacityrightnow错误;2、网页突然打不...
    99+
    2023-02-08
    ChatGPT
  • $_FILES数组为空的原因是什么
    这篇文章给大家分享的是有关$_FILES数组为空的原因是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。做上传的文件时候,打印$_files总是为空,查阅了下资料。发现是 ma...
    99+
    2024-04-02
  • 免费IP不能用的原因是什么
    这篇文章主要讲解了“免费IP不能用的原因是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“免费IP不能用的原因是什么”吧!1、免费代理IP可用性低。2、免费的代理IP,使用起来比较麻烦。选...
    99+
    2023-06-20
  • tomcat启动不起来是什么原因
    本篇内容主要讲解“tomcat启动不起来是什么原因”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“tomcat启动不起来是什么原因”吧!目录现象: 端口占用:文件拼写错误:现象:  tomcat安...
    99+
    2023-06-20
  • css3中动画性能高的原因是什么
    小编给大家分享一下css3中动画性能高的原因是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 性...
    99+
    2024-04-02
  • 代理ip不能上网的原因是什么
    这篇文章主要介绍了代理ip不能上网的原因是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。许多网络工作者需要使用代理IP。一些人会发现ip不能在使用代理IP的过程中使用。原...
    99+
    2023-06-20
  • Java不能真正泛型的原因是什么?
    目录简单来回顾一下类型擦除,看下面这段代码。为什么 Java 不能实现真正意义上的泛型呢?背后的原因是什么?第一,兼容性第二,不是“实现不了”总结简单来回顾一下类型擦除,看下面这段代...
    99+
    2024-04-02
  • java的ReentrantReadWriteLock不能锁升级的原因是什么
    本篇内容介绍了“java的ReentrantReadWriteLock不能锁升级的原因是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为...
    99+
    2023-06-20
  • Go数组比切片好的原因是什么
    这篇文章主要讲解了“Go数组比切片好的原因是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go数组比切片好的原因是什么”吧!前段时间有播放一条快讯,就是 Go1.17 会正式支持切片(S...
    99+
    2023-06-15
  • 数据库不能启动怎么查找原因
    数据库不能启动可能有多种原因,可以按照以下步骤查找原因: 检查数据库的日志文件:查看数据库的错误日志文件,通常可以在数据库的安装...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作