开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第1天,点击查看活动详情
前言
vue中一大特点就是响应式数据更新,当data当中的数据发生变化时视图会同步更新。vue中具体如何实现这一功能?这是我们必须掌握的知识,对于vue响应式原理我们不仅要会在说出来,更重要的是掌握代码逻辑最好能手写出来。vue2与vue3两个版本原理不一样,下面我们介绍下各自实现的原理。
vue2
vue2响应式主要通过Object.defineProperty()进行数据劫持实现数据的读取和更新,再通过观察者模式watcher和dep对数据进行收集更新。vue2响应式原理重点就是Object.definePropery()方法,我们要能够手写出来具体用法:
const obj = {
name: 'tpxz',
age: 26
};
Object.keys(obj).forEach((key) => {
const value = obj[key];
Object.defineProperty(obj, key, {
get() {
console.info('读取属性值');
},
set(newValue) {
console.info(newValue);
console.info('改变属性值');
}
});
});
obj.name;//读取了对象的值 打印出get里面的console.info
obj.age = 28;//修改了值 打印出set里面的console.info
所以当我们在vue中写的data,computed在更新值的时候内部都能够知道。但Object.defineProperty()主要针对于对象进行劫持,对数组数据和嵌套数据性能就不太好,为了更好地进行响应式更新vue3就采用了Proxy代理进行了数据劫持。
vue3
vue3选择了es6中的Proxy语法进行数据劫持,优化了响应式性能。Proxy可以创建对象代理,代理的对象可以是任何类型包括数组,创建好后直接返回代理对象。在回调函数读写的时候我们需要利用Reflect方法,所以vue3数据劫持就是Proxy+Reflect。
const obj = {
name: 'tpxz',
age: 26
};
const proObj = new Proxy(obj, {
get(target, prop) {
console.log(target); //目标对象obj
console.log(prop); //key
return Reflect.get(target, prop);
},
set(target, prop, newVal) {
console.log(val); //新值
return Reflect.set(target, prop, val);
}
});
//我们对代理后的数据进行修改
proObj.name;
proObj.age = 28;
总结
以上就是vue2跟vue3响应式原理,核心方法还是要能够手写出来一个案例的,具体的过程大家可以研究下代码,学习其中的思路。