各位观众老爷,晚上好!
今天咱们聊聊 Vue 2 源码里那些响应式属性的“爱恨情仇”,尤其是关于增删它们的一些限制,以及 Vue.set 和 Vue.delete 这两个“老朋友”的幕后故事。放心,我会尽量用大白话,争取让大家听得懂,记得住。
一、响应式世界的“潜规则”:为何要有增删限制?
首先,我们要明白 Vue 2 的响应式系统,是基于 Object.defineProperty 来的。简单来说,就是给对象的每个属性都加上 getter 和 setter。当属性被读取时,getter 会收集依赖(也就是用到这个属性的组件);当属性被修改时,setter 会通知这些依赖进行更新。
但是!Object.defineProperty 只能劫持已经存在的属性。也就是说,如果你动态地给对象添加一个属性,或者删除一个属性,Vue 是不知道的,也就没法触发响应式更新了。
这就好比,你给一个房子装了监控系统(Object.defineProperty),监控着每个房间(属性)。但是,后来你又偷偷加盖了一个房间,或者拆掉了一个房间,监控系统就懵逼了,完全不知道发生了什么。
所以,Vue 2 的官方文档才反复强调,避免在 data 中动态添加或删除属性。
二、Vue.set:响应式“开后门”的英雄
既然