vue2中,对于数组和对象是没有办法进行响应的
所以通过中间处理进行数据拦截,但是前提条件是不改变原有push,pop这些方法的原有行为。
vue 源码
简单实现代码
var interception = [
"push",
"pop",
"shift",
"unshift",
"splite",
"sort"
];
var arrayProto = Array.prototype;
//代理原型对象
var proxyProtoObj = Object.create(arrayProto);
interception.forEach(function(method){
proxyProtoObj[method] = function(){
//1: 保留原有的行为
var res = arrayProto[method].apply(this, arguments);
//2: 拦截
console.log("拦截你对于"+method+"的操作");
return res;
}
})
var arr = [1, 2, 3, 4, 5];
arr.__proto__ = proxyProtoObj;
arr.push(6);
console.log(arr)
vue2.x 源码的书写
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
});
});