在学习之前,我们需要问一个为什么,为什么vue2 源码要重写数组方法
-
响应式数据更新:通过重写数组方法,Vue 能够捕获对数组的变更操作(如 push、pop、shift 等),并在数据发生变化时自动更新视图,实现了数据的响应式更新。
-
侦测变更:重写数组方法使 Vue 能够侦测到数组的变更,从而触发相应的更新。这样,当修改了数组的内容时,视图能够及时地做出相应的变化。
-
便捷的操作语法:通过重写数组方法,Vue 使开发者能够直接对数组进行操作而无需手动触发视图更新,提供了一种更加便捷的操作语法。
-
保持一致性:通过统一对数组方法的处理,Vue 2.x 在处理数组变更时能够保持代码的一致性和可维护性。
总的来说,重写数组方法使得 Vue 能够更好地支持响应式数据更新,提供了更加便捷和灵活的数据操作方式,从而使得开发者能够更加轻松地管理和操作数据,同时保持了视图和数据的一致性。
// 保存数组原型方法的引用
const arrayProto = Array.prototype;
// 创建一个新的对象,继承自数组原型
const arrayMethods = Object.create(arrayProto);// 重写数组的变异方法
['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].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) {case 'push':case 'unshift':inserted = args;break;case 'splice':inserted = args.slice(2);break;}if (inserted) ob.observeArray(inserted);// 触发更新ob.dep.notify();return result;});
});// 重写之后的数组方法挂载到数组的原型上
function def(obj, key, val, enumerable) {Object.defineProperty(obj, key, {value: val,enumerable: !!enumerable,writable: true,configurable: true});
}// 最后,将重写后的数组方法挂载到数组原型上
def(arrayProto, '$set', function $set(index, val) {// ... $set 方法的具体实现
}, false);def(arrayProto, '$delete', function $delete(index) {// ... $delete 方法的具体实现
}, false);export { arrayMethods };