Vue3.0源码逐行解析(三):响应系统
2023-11-11 11:23:28
Vue3.0源码逐行解析(三):响应系统
Vue2 和 Vue3 的响应式系统概念从框架本身来看没有任何改变。我们来回顾下 Vue2 说:
-
数据变化时通知视图更新
-
通过 Object.defineProperty实现
Vue3说:
-
数据变化时通知视图更新
-
通过 Proxy实现
虽然概念相似,但底层实现方式却有本质的不同。Vue2 采用的是 ES5 Object.defineProperty,而 Vue3 则采用了 ES6 Proxy。
Vue2 的响应式系统
Vue2 中,通过 Object.defineProperty 来劫持对象的属性,当属性值发生改变时,触发 setter 方法,从而实现响应式更新。这种方式虽然简单易懂,但是在某些情况下存在一定的局限性,例如:
-
无法劫持数组的变化
-
无法劫持对象的新增属性
-
无法劫持对象属性的删除
Vue3 的响应式系统
Vue3 中,通过 Proxy 来劫持整个对象,当对象内部发生任何变化时,都会触发 Proxy 的相关方法,从而实现响应式更新。这种方式不仅解决了 Vue2 中存在的局限性,而且还带来了以下优势:
-
可以劫持数组的变化
-
可以劫持对象的新增属性
-
可以劫持对象属性的删除
-
性能更好
Vue3 中如何使用 Proxy 实现响应式数据
在 Vue3 中,通过 createReactive 函数来创建响应式数据。该函数内部使用 Proxy 来劫持对象,并返回一个响应式代理对象。
function createReactive(target) {
return new Proxy(target, {
get(target, key, receiver) {
// ...
},
set(target, key, value, receiver) {
// ...
},
// ...
});
}
当我们使用响应式代理对象时,对其进行任何操作,都会触发 Proxy 的相关方法,从而实现响应式更新。
举个例子
const obj = createReactive({
name: '张三',
age: 18
});
obj.name = '李四';
console.log(obj.name); // '李四'
在上面的例子中,当我们修改 obj.name 的值时,触发了 Proxy 的 set 方法,从而实现了响应式更新。
Vue3 的响应式系统相比于 Vue2 有哪些优势
-
性能更好:Proxy 的性能要优于 Object.defineProperty。
-
更全面:Proxy 可以劫持数组的变化、对象的新增属性、对象属性的删除等,而 Object.defineProperty 无法做到这一点。
-
更灵活:Proxy 可以通过不同的配置来实现不同的响应式行为,而 Object.defineProperty 则相对比较死板。