【vue】如何改写数组的方法使其成为响应式?

  • Post author:
  • Post category:vue


vue2是怎么进行数组的方法重写的?

在vue2的响应式中,数组的一些方法是无法实现响应式,需要进行重写,如何实现的呢??

在Vue中,对响应式处理利用的是Object.defineProperty对数据进行拦截,vue没有对数组进行响应式处理,例如数组内部变化、数组长度变化、数组的截取变化等等,对这些操作进行hack,让vue能够监听到其中变化

  • push()、pop()、shift()、unshift()、splice()、sort()、reverse()



如何实现

那Vue是如何实现让这些数组方法实现元素的实时更新的呢,下面是Vue中对这些方法的封装:

//缓存数组原型
const arrayProto = Array.prototype;

//实现arrayMethods.__proto__ == Array.prototye
export const arrayMethods = Object.create(arrayProto);

//需要进行功能扩展的方法
const methodsToPatch = [
  "push",
  "pop",
  "shift",
  "unshift",
  "splice",
  "sort",
  "reverse"
];

//intercept mutating methods and emit events

methodsToPatch.forEach(function(method){
  const original = arrayProto[method];
  def(arrayMethods,method,function mutator(...args){
    //执行并缓存原生数组的功能
    const result = original.apply(this,args);
    //响应式处理
    const ob = this.__ob__;
    let inserted;
    switch(method){
      //push,unshift会增加新的索引,要手动obsever
      case "push":
      case "unshift":
        inserted = args;
        break;
      case "splice":
        inserted = args.slice(2);
        break;
    }

    if(inserted) ob.observerArray(inserted);
    ob.dep.notify();
    return result;
  })
})

简单来说就是,重写了数组中的那些原生方法,首先获取到这个数组的__ob__,也就是它的Observer对象,如果有新的值,就调用observeArray继续对新的值观察变化(也就是通过target__proto__ == arrayMethods来改变了数组实例的型),然后手动调用notify,通知渲染watcher,执行update。



版权声明:本文为zhaohb2016原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。