vue是如何监测Object的变化呢?Object.defineProperty()
监测对象的变化:
- Object.defineProperty() (vue2)
- Proxy (vue3)
Object.defineProperty()
Object.defineProperty(object, key, { value: 18, // 赋值 enumerable: true, // 控制属性是否可以枚举,默认值是false writable: true, // 控制属性是否可以被修改 configurable: true, // 控制属性是否可以被删除 // 当 key 被读取的时候触发 // get:function () { // }, // // 当key 被修改的时候触发 // set:function(newVal) { // } })
// 没修改之前的值 let oldData = { name: "张三", age: 18, girlFriends: { one: "xiaoshishi", two: "xiaobobo" } } // 修改之后的值 let newData = { name: "张三", age: 18, girlFriends: { one: { name:'xiaoshishi', boyFriend:{ one:'kunkun', two: 'liudehua' } }, two: "dabobo", } } Object.keys(oldData).map((key) => { defineProperty(oldData, key, newData[key]) })
这里是重点
function defineProperty(data, key, value) {
Observer(value)
Object.defineProperty(data, key, { enumerable: true, // 控制属性是否可以枚举,默认值是false configurable: true, // 控制属性是否可以被删除 get: function () {return value }, // 指写入属性时调用的函数。 set: function (newVal) { if (value === newVal) { return } else { value = newVal } } }) }
Observer
//利用递归 判断子属性的类型 是不是 ’object‘ 递归添加 getter setter属性
function Observer(value) {
if (typeof value === 'object') {
Object.keys(value).map((key,i) => { defineProperty(value, key, value[key]) }) } }
这里遇到的坑:使用Object.defineProperty方法时,报错。在使用了get,set任何一个配置时不允许再出现value,writable任何一个,否则将会报错,因为两者的功能是一样的,不允许重复声明。
我不制造bug,我只是bug的搬运工。