响应式原理
官网对于响应式原理的介绍:https://cn.vuejs.org/v2/guide/reactivity.html
写在前面
vue3 的改变主要有以下几点:
- 实现响应式的 api 由
defineProperty
改为proxy
- 副作用 effect(代替 vue2 的 Observer、Watcher 模块)
其他的还有 Composition API、缓存事件处理函数、Block Tree、拥抱 ts…
详情可以参考 Vue3 对比 Vue2.x 差异性、注意点、整体梳理
Proxy
Proxy 是 vue3 实现响应式更新的基石。这个 api 的作用是代理对象,可以拦截对对象的操作,vue3 主要用到了 Proxy 的两个 api 来实现响应式数据:
// 拦截对象属性的访问
get(target, prop, receiver)
// 拦截对象属性的设置,最后返回一个布尔值
set(target, prop, value, receiver):
但是 Proxy 不支持 IE,所以说 vue3 使用 Proxy 也意味着抛弃 IE
更多内容可以参考 Proxy - MDN
简单实现对象数据的响应式如下:
function createReactiveObject(target) {
if (!isObject(target)) {
return target;
}
const baseHandler = {
get(target, key, receiver) {
const res = Reflect.get(target, key, receiver);
return isObject(res) ? reactive(res) : res;
},
set(target, key, value, receiver) {
const res = Reflect.set(target, key, value, receiver);
return res;
},
};
const observed = new Proxy(target, baseHandler);
return observed;
}
可以看到,如果我们访问和增加一个不存在的属性,同样也会触发get
和set
操作。这样就不必使用$set
这个 api 了。
当访问的 key 是一个对象时,会触发递归(如果不访问这个对象,就永远不会去做这一步递归操作),比如下面这个例子:
data = {
title: "007",
person: {
name: