vue响应式
// vue响应式原理
const Observer = function(data) {
// 循环修改每个属性,添加get set
for(let key in data) {
defineReactive(data,key);
}
}
const defineReactive = function(obj,key) {
// 局部变量dep,用于get set内部调用
const dep = new Dep();
// 获取当前值
let val = obj[key];
Object.defineProperty(obj,key, {
// 当前属性可被循环
enumerable: true,
// 当前属性可被修改
configurable: true,
get() {
// 调用依赖收集器中的addSub,用于收集当前属性与watcher中的依赖关系
dep.depend();
return val;
},
set(newVal) {
if(newVal === val) {
val = newVal;
// 当值发生变更时,通知依赖收集器,更新每个需要更新的watcher
dep.notify();
}
}
})
}
const observe = function(data) {
return new Observer(data);
}
const Dep = function() {
const self = this;
// 收集目标
this.target = null;
// 存储收集器中需要通知的Watcher
this.subs = [];
// 当有目标时,绑定Dep和watcher的关系
this.depend = function() {
if(Dep.target) {
Dep.target.addDep(self);
}
}
// 为当前收集器添加Watcher
this.addSub = function(watcher) {
self.subs.push(watcher);
}
this.notify = function() {
for(let i=0;i<self.subs.length;i +=1) {
self.subs[i].update();
}
}
}
const Watcher= function(vm, fn) {
const self = this;
this.vm = vm;
// 将当前Dep.target 指向自己
Dep.target = this;
this.addDep = function(dep) {
dep.addSub(self);
}
this.update= function() {
console.log('in watcher update');
fn();
}
this.value = fn();
Dep.target = null;
}
const Vue = function(options) {
const self = this;
// 将data赋值给this._data,源码此处通过proxy代码劫持数据
if(options && typeof options.data === 'function') {
this._data = options.data.apply(this);
}
// 挂载函数
this.mount = function() {
new Watcher(self,self.render)
}
// 渲染函数
this.render = function() {
with(self) {
this._data.text;
}
}
// 监听this._data
observe(this._data)
}
const vue = new Vue({
data() {
return {
text: 'Hello world!'
}
}
})
vue.mount();
vue._data.text = '123';
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
编辑 (opens new window)
上次更新: 2022/09/18, 15:06:58