手写Vue (1) 数组劫持

1. 我们重新编写一个文件 

创建  array.js

2. 拿到数组上的所有方法 

let oldArrayProtoMethods = Array.prototype;

3.通过 Object.create()  创建 新的 方法 

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
拷贝的新的对象 可以查找到老的方法 
export let arrayMethod = Object.create(oldArrayProtoMethods);

 

4. 声明7个方法 

 

 

let methods = [
  'push',
  'pop',
  'unshift',
  'shift',
  'sort',
  'splice',
  'reverse'
]

 

6.重写数组方法 加入自己的操作  

methods.forEach(method => {
  console.log(method)
  arrayMethod[method] = function (...args) {
    let r = oldArrayProtoMethods[method].apply(this, args)
    console.log('调用数据更新的方法')
  }
})

遍历数组方法 拿到原来的数组方法 改变this 指向 指向为   arrayMethod

7. 将这些方法挂载到数组的原型上

if (Array.isArray(data)) {
      // 只能拦截数组方法 数组的每一个项还需要观测
      console.log('监听数组')
      data._proto = arrayMethod
    } 

8.测试

index.js

import Vue from '../source/src/index';
let vm = new Vue({
  el: '#app',
  data() {
    return {
      msg: 'hello',
      school: {
        name: 'zf',
        age: 10
      },
      arr: [1, 2, 3]
    }
  },
  computed: {

  },
  watch: {

  }
})
vm.arr.push(1111)
console.log(vm.arr)  // hello

9.测试结果

 

 

 

10.push  进去的数组可能是一个对象 所以我们应该对数组里面的项的对象进行监听

先明确 只有  push   unshift    slice 有新增数组的功能 所以我们 要在这几个方法进行监听 

let inserted;
    switch (key) {
      case 'push':
      case 'unshift':
        inserted = args
        break;
       case 'splice':
      // 获取新增的
        inserted = args.slice(2)
        break;
      default:
        break;
    }
    if (inserted) observerArray(inserted)

11.遍历监听新增的项 循环数组 依次对数组新增的每一项进行观测

export function observerArray(inserted) {
  for (let i = 0; i < inserted.length; i++) {
    observe(inserted[i])
  }
}

12. 在 observer.js  观测数组中 的每一个项

    // 观测数组的每一个项
      observerArray(data)

13. 测试

index.js

import Vue from '../source/src/index';
let vm = new Vue({
  el: '#app',
  data() {
    return {
      msg: 'hello',
      school: {
        name: 'zf',
        age: 10
      },
      arr: [1, 2, 3]
    }
  },
  computed: {

  },
  watch: {

  }
})
vm.arr.push({ a: 1 })
console.log(vm.arr[3].a)  // hello

14 .测试结果 

 

码云 :https://gitee.com/guangzhou110/handwritten_vue/tree/master/vue%20%E6%95%B0%E7%BB%84%E5%8A%AB%E6%8C%81

posted @ 2020-04-08 21:41  1点  阅读(441)  评论(0)    收藏  举报