手写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

相关推荐:

Python中如何实现NumPy数组的符号函数运算_利用sign函数判断正负

np.sign()返回整数1、-1、0分别表示正、负、零;复数返回单位复数;不区分±0.0;用作布尔掩码前须处理零值,性能依赖数据类型,不支持非数值类型。 NumPy的np.sign()到底返回什么值 np.sign()对数组元素逐个判断符号,返回整数:正数→1,负数→-1,零→0。注意它不区分+0...

如何在Python中对NumPy数组进行转置与轴换位操作?

NumPy数组转置与轴换位本质相同但接口语义不同:.T仅适用于二维数组的简单转置,三维及以上会完全反转轴序;精确控制需用np.transpose()、np.swapaxes()或np.moveaxis()。 NumPy数组的转置和轴换位本质是同一类操作,但接口不同、语义侧重不同:用.T或np.tra...

如何在 NumPy 中将二维数组沿新轴扩展为三维数组

本文介绍多种高效、内存友好的方法,将二维NumPy数组沿新增的第一维(axis=0)重复扩展为三维数组,涵盖np.expand_dims+np.repeat、np.tile、广播机制等主流方案,并对比其性能与适用场景。 本文介绍多种高效、内存友好的方法,将二维numpy数组沿新增的第一维(axis=...

Python中如何计算NumPy数组的特征值与特征向量_使用linalg.eig

np.linalg.eig返回的特征向量是列向量,即v[:,i]对应第i个特征值w[i],但print(v)屏幕显示按行展示,易误读为“每行一个向量”;实际布局符合线性代数惯例,验证方式为检查A@v[:,0]≈w[0]*v[:,0]。 为什么linalg.eig返回的特征向量是列向量,但结果却是按行...