deepProxy

第一步

如果初始数据是多层对象嵌套的话,按照目前的逻辑,无法对深层对象进行代理,如下代码,值改变后,effect 不会重新执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>

<script type="module">
import { reactive, effect } from './reactivity.js';

let obj = { name: 'xiaoming', age: 18, flag: true, address: { name: 1 } };
const state = reactive(obj);

effect(() => {
app.innerHTML = state.address.name;
})

setTimeout(() => {
state.address.name = 2;
}, 1000);
</script>
</body>
</html>

第二步

对深层对象进行代理

baseHandler.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { ReactiveFlags } from './constants';
import { activeEffect } from './effect';
import { track, trigger } from './reactiveEffect';
import { isObject } from '@vue/shared';
import { reactive } from './reactive';

export const mutableHandlers: ProxyHandler<any> = {
get(target, key, receiver) {
if (key === ReactiveFlags.IS_REACTIVE) {
return true;
}

// 收集 target 这个对象上的 key 属性,和 effect 关联起来
track(target, key);

const res = Reflect.get(target, key, receiver);

// -----------------------------新增开始-----------------------------
// 当取出来的值是对象的时候,需要对这个对象再次代理
if (isObject(res)) {
return reactive(res)
}
// -----------------------------新增结束-----------------------------

return res;
},
...
};