1. Vue でカプセル化される配列メソッドとは何か、およびページ更新の実装方法
Vue では、応答処理のためにデータをインターセプトするために Object.defineProperty が使用されますが、このメソッドは配列の内部変更、配列の長さの変更、配列のインターセプトの変更などを監視できないため、これらの操作はVue の変更を監視できるようにハッキングされる可能性があります。
では、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
*/
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) によって変更され、手動で notification を呼び出してレンダリング ウォッチャーに通知し、更新を実行します。