数据是怎么发生变化的?
数据是怎么发生变化的?vue3之前是使用Object.defineProperty这个api来对需要侦测变化的数据进行拦截,添加get,set方法,这样就可以知道数据什么时候被修改。
**
* 将传入的obj,动态的设置一个key,它的值是val
* @param {Object} obj 要接收的对象
* @param {String} key 要设置的键
* @param {*} val 要设置的值
*/
function defineReactive(obj, key, val) {
// * 如果原始对象的值是对象,那么还是需要递归遍历该值
observe(val);
// - 要拦截的对象obj
// - 要设置的属性名称
// - descriptor属性描述器,是一个对象,里面有set和get方法
Object.defineProperty(obj, key, {
get() {
// 返回的是最新的值
console.log('get key', key); // sy-log
return val;
},
set(v) {
// 如果老的值与新传进来的值不相等 设置为最新的值。这样get里面拿到的就是最新的值
if (val !== v) {
console.log('set key', key); // sy-log
// 因为传入的新值v可能还是一个对象, 所以需要遍历。
observe(v);
val = v;
}
},
});
}
/**
* 递归遍历传入的对象,动态拦截该对象上的所有的key
* @param {Object} obj 要递归遍历的对象
*/
function observe(obj) {
// 如果传入的不是对象 直接返回该值
if (typeof obj !== 'object' || obj === null) {
return obj;
}
Object.keys(obj).forEach((key) => {
// 响应式的设置值。
defineReactive(obj, key, obj[key]);
});
}
const obj = {
foo: 'foo',
bar: 'bar',
baz: {
a: 1,
},
};
// defineReactive(obj, 'name', 'henry');
observe(obj);
obj.name;
obj.name = 'foooooo';
set(obj, 'baz', { a: 10 });
console.log(obj.baz);