02_vue2_reactive

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class Watcher {
static _effect = null
static WatchEffect(effect) {
Watcher._effect = effect
effect()
Watcher._effect = null
}
}
/**
*
*
* @class Dep
*/
class Dep {
constructor() {
this.watchers = new Set()
}
depend() {
this.watchers.add(Watcher._effect)
}
notify() {
this.watchers.forEach(watcher => watcher instanceof Function && watcher())
}
}
/**
* depMap :
* {
* obj_1:{prop_key_01:dep},
* obj_2:{prop_key_02:dep}
* }
*/
const depMap = new WeakMap()
function getDep(obj, prop_key) {
let wrap = depMap.get(obj)
if (!wrap) {
wrap = new Map()
depMap.set(obj, wrap)
}
let dep = wrap.get(prop_key)
if (!dep) {
dep = new Dep()
wrap.set(prop_key, dep)
}
return dep
}
function useReactive(data) {
let _data = {}
for (const prop_key in data) {
const dep = getDep(data, prop_key)
Object.defineProperty(_data, prop_key, {
get() {
dep.depend()
return data[prop_key]
},
set(newVal) {
data[prop_key] = newVal
dep.notify()
return data[prop_key]
}
})
}
return _data
}

let vm = useReactive({ name: 'jiujue', age: 12 })
Watcher.WatchEffect(function() {
console.log('effect fn exec->', vm.name)
})

03_vue3_reactive

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class Watcher {
static _effect = null
static WatchEffect(effect) {
Watcher._effect = effect
effect()
Watcher._effect = null
}
}
/**
*
*
* @class Dep
*/
class Dep {
constructor() {
this.watchers = new Set()
}
depend() {
this.watchers.add(Watcher._effect)
}
notify() {
this.watchers.forEach(watcher => watcher instanceof Function && watcher())
}
}
/**
* depMap :
* {
* obj_1:{prop_key_01:dep},
* obj_2:{prop_key_02:dep}
* }
*/
const depMap = new WeakMap()
function getDep(obj, prop_key) {
let wrap = depMap.get(obj)
if (!wrap) {
wrap = new Map()
depMap.set(obj, wrap)
}
let dep = wrap.get(prop_key)
if (!dep) {
dep = new Dep()
wrap.set(prop_key, dep)
}
return dep
}
function useReactive(data) {
return new Proxy(data, {
get(target, prop_key) {
getDep(target, prop_key).depend()
return data[prop_key]
},
set(target, prop_key, newVal) {
data[prop_key] = newVal
getDep(target, prop_key).notify()
return data[prop_key]
}
})
}
/*let vm = useReactive({ name: 'jiujue', age: 12 })
Watcher.WatchEffect(function() {
console.log('effect name fn exec-> vm.name', vm.name)
})
Watcher.WatchEffect(function() {
console.log('effect age fn exec-> vm.age', vm.age)
})
Watcher.WatchEffect(function() {
console.log('effect age fn exec-> vm.age && age', vm.name, vm.age)
})*/