类别:vue / 日期:2022-08-25 / 浏览:505 / 评论:0
在 Vue 中,对响应式处理利用的是 Object.defineProperty 对数据进行拦截,而这个方法并不能监听到数组内部变化,数组长度变化,数组的截取变化等,所以需要对这些操作进行 hack,让 Vue 能监听到其中的变化。
Vue将被侦听的数组的变更方法进行了包裹,所以他们也将会触发视图更新,这些被包裹过的方法包括
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
那 Vue 是如何实现让这些数组方法实现元素的实时更新的呢,下面是 Vue 中对这些方法的封装:
// 缓存数组原型const arrayProto = Array.prototype;
// 实现 arrayMethods.__proto__ === Array.prototype
export const arrayMethods = Object.create(arrayProto);
// 需要进行功能拓展的方法
const methodsToPatch = [
"push",
"pop",
"shift",
"unshift",
"splice",
"sort",
"reverse"
];
/**
* Intercept mutating methods and emit events
*/1
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会新增索引,所以要手动observer
case "push":
case "unshift":
inserted = args;
break;
// splice方法,如果传入了第三个参数,也会有索引加入,也要手动observer。
case "splice":
inserted = args.slice(2);
break;
}
if (inserted) ob.observeArray(inserted); // 获取插入的值,并设置响应式监听
// notify change
ob.dep.notify(); // 通知依赖更新
// 返回原生数组方法的执行结果
return result;
});
});简单来说就是,重写了数组中的那些原生方法,首先获取到这个数组的__ob__,也就是它的 Observer 对象,如果有新的值,就调用 observeArray 继续对新的值观察变化(也就是通过target__proto__ == arrayMethods来改变了数组实例的型),然后手动调用 notify,通知渲染 watcher,执行 update。
版权声明 : 本文未使用任何知识共享协议授权,您可以任何形式自由转载或使用。
发表评论 / 取消回复