【重學前端框架】Vue中對數組的處理(二)

前言

上一節Vue中的視圖更新原理說到默認的defineProperty能夠攔截到經過數組下標方式修改的值的變動,可是Vue中爲了更好的性能和用戶體驗而對數組單獨進行了處理,那Vue中到底是如何來處理的呢?vue

Vue對數組的處理

vue源碼以下:segmentfault

var arrayProto = Array.prototype;
var arrayMethods = Object.create(arrayProto);

var methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
];

/**
 * Intercept mutating methods and emit events
 */
methodsToPatch.forEach(function (method) {
  // cache original method
  var original = arrayProto[method];
  def(arrayMethods, method, function mutator () {
    var args = [], len = arguments.length;
    while ( len-- ) args[ len ] = arguments[ len ];

    var result = original.apply(this, args);
    var ob = this.__ob__;
    var inserted;
    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
  });
});
/**
 * Define a property.
 */
function def (obj, key, val, enumerable) {
  Object.defineProperty(obj, key, {
    value: val,
    enumerable: !!enumerable,
    writable: true,
    configurable: true
  });
}

也就是說vue中基於原生Array的原型對象建立了一個新對象,從新定義了數組中的如下方法:數組

'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'

將以上方法定義經過defineProperty定義成了響應式, 對於push、unshift、splice方法給數組新增值時還作了特別的處理。在vue中直接操做以上方法修改數組值,視圖都能響應。app

Object.defineProperty做爲vue2.0響應式的核心將在vue3.0 被Proxy取代。由於前者存在一些侷限,前者不能監聽到對象的屬性的增長和刪除,以及不能監聽到數組經過原生的方法對數組作的修改等問題,後者提供了對更多種類數據的攔截和對對象更好的支持。post

image.png

下一篇,寫寫Proxy的使用。性能

參考資料this

Vue 3.0 計劃spa

相關文章
相關標籤/搜索