- 原因:Obejet.defineproperty无法监听到数组和对象的内部的变化,所以vue2.0重写了常用的数组的方法来使得数组更新的时候触发页面的更新,对象的更新则使用this.$set,使得对象更新的时候触发页面的更新
- vue2重写了哪些数组方法
var methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
];
如果使用这7种以外的数组方法实现数据和视图同时更新则使用this.$set来实现更新
var arrayProto = Array.prototype;
var arrayMethods = Object.create(arrayProto);
methodsToPatch.forEach(function (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); }
ob.dep.notify();
return result
});
});
由上述代码可见,由于push、unshift、splice会让数组索引发生改变,所以需要手动触发
observer,这里的方法是定义一个inserted来控制是否触发响应式更新,如果为true,则
用`ob.observeArray(inserted);`来手动给新插入的值设置响应式监听,再用
`ob.dep.notify()`通知依赖更新,最后返回原生数组方法处理后的值` return result`。
链接:vue对于常用数组方法重写的原因和源码的学习(vue面试必会知识点) - 起源地 (qiyuandi.com)