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 .测试结果