实现数组响应式主要有以下三个步骤。

  • 找到数据原型
  • 覆盖那些能够修改数组的更新方法[push,pop,shift,unshift,splice,sort,reverse],使其可以通知更新
  • 将得到的新的原型设置到数据实例原型上
//第一步,找到数据原型
const originalProto=Array.prototype
//备份,进行修改,不能直接修改原型
const arrayProto=Object.create(originalProto)
//第二步 覆盖那些能够修改数组的更新方法
const arrayMethods=['push','pop','shift','unshift','splice','sort','reverse'];
arrayMethods.forEach(method=>{
  const original = arrayProto[method];
  def(arrayMethods, method, function() {
    var args = [], len = arguments.length;
    while ( len-- ) args[ len ] = arguments[ len ];
    var result = original.apply(this, args);
    var ob = this.__ob__;
    var inserted;
    console.log(method)
    switch (method) {
     
      case 'push':
      case 'unshift':
        inserted = args;
        break
      case 'splice':
        inserted = args.slice(2);
        break
    }
    if (inserted) { ob.observeArray(inserted); }
    // notify change 使其可以通知更新
    ob.dep.notify();
    return result
  });
})
//第三步 将得到的新的原型设置到数据实例原型上
 // 辨别类型
if (Array.isArray(value)) {
    var hasProto = '__proto__' in {};
    if(hasProto){
    value.__proto__=arrayMethods;
    }else{
      const arrayKeys = Object.getOwnPropertyNames(arrayMethods);
      copyAugment(value, arrayMethods, arrayKeys);
    }
    this.observeArray(value);
    // todo
} else {
    this.walk(value)
}
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

具体实现代码在 github 上有详细代码。github地址 (opens new window)

Last Updated: 8/11/2020, 11:11:04 PM