ts
1// 代理简单类型,通过js对象访问器对对象的属性进行获取和设置
2const ref = (raw = null) => {
3 const r = {
4 // 对象的value属性获取
5 get value() {
6 track(r, 'value')
7 return raw
8 },
9 // 对象的value属性设置
10 set value(newVal) {
11 if (raw != newVal) {
12 raw = newVal
13 trigger(r, 'value')
14 }
15 }
16 }
17 return r
18}
19
20// 代理对象,在get,set方法中追踪属性和重新触发effect函数
21const reactive = (target) => {
22 return new Proxy(target, {
23 get (target, key, receiver) {
24 // const res = Reflect.get(target, key, receiver)
25 track(target, key)
26 return Reflect.get(target, key, receiver)
27 },
28 set (target, key, newVal, receiver) {
29 const oldVal = target[key]
30 const res = Reflect.set(target, key, newVal, receiver)
31 if (oldVal != newVal) {
32 trigger(target, key)
33 }
34 return res
35 }
36 })
37}
38
39let price = 1;
40let total = 1;
41
42let obj = reactive({
43 title: 'tttt',
44 num: 1,
45 child: {
46 title: 'ssss',
47 num: 2
48 }
49})
50
51let totalPrice = 0
52
53let text = ''
54
55// 存储每个属性对应的effect函数
56// const dep = new Set()
57
58// 存储所有 属性: effects 对象{ key: dep }
59// const depMap = new Map()
60
61// weakMap弱引用,其他对象不引用它,垃圾回收机制自动回收, key值只能是对象
62const targetMap = new WeakMap()
63
64let activeEffect = null
65
66const effect = (eff) => {
67 activeEffect = eff
68 activeEffect()
69 activeEffect = null
70}
71
72// 追踪属性
73const track = (target, key) => {
74 if (activeEffect) {
75 let depMap = targetMap.get(target)
76 if (!depMap) {
77 targetMap.set(target, depMap = new Map())
78 }
79 let dep = depMap.get(key)
80 if (!dep) {
81 depMap.set(key, dep = new Set())
82 }
83 dep.add(activeEffect)
84 }
85}
86
87// 触发重新执行effect函数
88const trigger = (target, key) => {
89 let depMap = targetMap.get(target)
90 if (!depMap) return
91 let dep = depMap.get(key)
92 if (dep) {
93 dep.forEach(effect => {
94 effect()
95 });
96 }
97}
98
99effect(() => {
100 text = obj.title + obj.num
101})
102
103console.log(text)
104