Vue中为什么不能检测数组的变化-01-defineProperty
Vue2.0对于响应式数据的实现有一些不足:
- 无法检测数组/对象的新增
- 无法检测通过索引改变数组的操作。
Vue2.0中响应式数据是通过Object.defineProperty实现,因此无法检测数组/对象的新增,但为什么无法检测到通过索引改变数组的操作呢?也是因为Object.defineProperty的原因么?
官方文档中对于这两点都是简要的概括为“由于JavaScript的限制”无法实现,而Object.defineProperty是实现检测数据改变的方案,那这个限制是指Object.defineProperty吗?
无法检测数组的索引变化?
我们来测试一下看看。以下例子,对遍历数组中的每一项,用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)
说明:Vue对数组的7个变异方法(push、pop、shift、unshift、splice、sort、reverse)实现了响应式,因此这里我们就不做测试了。
通过索引改变arr[1],可以发现触发了set,也就是Object.defineProperty是可以检测到通过索引改变数组的操作的,那Vue2.0为什么没有实现呢?
一位开发小哥在github对尤大大提了issue,回答如下:
尤大大回答是因为性能问题。看来不是JavaScript的锅,更不是Object.defineProperty的锅了。
验证
通过我们上面的测试,Object.property是可以检测到通过索引改变数组的操作的,而Vue没有实现。那我们看看源码,Vue的实现逻辑是怎样的?
我们改下对数组的操作逻辑,遍历数组对每一项采用Object.defineProperty进行检测
此时点击按钮2,可以发现数值改变为0了,说明通过索引改变arr的操作被检测到了,Vue是可以实现的!我们进一步确认下:
在defineReactive的Object.defineProperty的set中,加一行console.log,可以发现,当点击按钮2时,控制台会输出“set 0”,更加确切的说明
arr[index]=0
被set检测到了。由于以上提到的问题,Vue3.0采用Proxy替代了Object.defineProperty,Proxy可以完美解决吗?
下一篇
本文来自博客园,作者:JackieDYH,转载请注明原文链接:https://www.cnblogs.com/JackieDYH/p/17634349.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现