# 手写一些Vue的代码
# 实现一个Vue的响应式原理
// 实现被观察者类,就是收集依赖的
class Dep {
constructor() {
this.subs = []
}
addSub(watcher) {
this.subs.push(watcher)
}
notify(data) {
this.subs.forEach(sub => sub.update(data))
}
}
// 实现观察者类
class Watcher {
constructor(cb){
this.cb =cb
}
update(data) {
this.cb(data)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Dep
被观察者类,提供用来收集观察者(addSub
)方法和通知观察者(notify
)方法;Watcher
观察者类,实例化时支持传入回调(cb
)方法,并提供更新(update
)方法;
// 实现响应式类
class Observer {
constructor(node,data) {
this.defineReactive(node,data)
}
defineReactive(vm,obj) {
for(let key in obj) {
let value = obj[key],dep=new Dep()
Object.defineProperty(obj,key,{
enumerable: true,
configurable: true,
get() {
let watcher = new Watcher(v => vm.innerText = v)
dep.addSub(watcher)
return value
},
set(newValue) {
value = newValue
//通知观察者
dep.notify(newValue)
}
})
}
}
}
// 例子
let initData = {
text: '你好,前端自习课',
desc: '每日清晨,享受一篇前端优秀文章。'
};
const app = document.querySelector('#app');
// 步骤1:为测试数据转换为响应式对象
new Observer(app, initData);
// 步骤2:初始化页面文本内容
app.innerText = initData.text;
// 步骤3:绑定按钮事件,点击触发测试
document.querySelector('#update').addEventListener('click', function(){
initData.text = `我们必须经常保持旧的记忆和新的希望。`;
console.log(`当前时间:${new Date().toLocaleString()}`)
})
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
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
← css画东西