vue2源码重写数组方法学习

在学习之前,我们需要问一个为什么,为什么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 };
Vue.js 2.x 中,为了实现响应式的数组,你可以使用下面的方法重写数组方法: 1. push:使用 `Array.prototype.push` 方法,然后手动调用 `Vue.set` 更新数组,例如: ```javascript this.array.push(newItem); Vue.set(this.array, this.array.length - 1, newItem); ``` 2. pop:使用 `Array.prototype.pop` 方法,然后手动调用 `Vue.delete` 删除最后一个元素,例如: ```javascript const deletedItem = this.array.pop(); Vue.delete(this.array, this.array.length); ``` 3. shift:使用 `Array.prototype.shift` 方法,然后手动调用 `Vue.delete` 删除第一个元素,例如: ```javascript const deletedItem = this.array.shift(); Vue.delete(this.array, 0); ``` 4. unshift:使用 `Array.prototype.unshift` 方法,在调用之前手动调用 `Vue.set` 更新数组的长度,例如: ```javascript this.array.unshift(newItem); Vue.set(this.array, 0, newItem); ``` 5. splice:使用 `Array.prototype.splice` 方法,然后手动调用 `Vue.delete` 删除或添加元素,例如: ```javascript // 删除元素 const deletedItems = this.array.splice(startIndex, deleteCount); for (let i = 0; i < deleteCount; i++) { Vue.delete(this.array, startIndex + i); } // 添加元素 this.array.splice(startIndex, 0, ...newItems); for (let i = 0; i < newItems.length; i++) { Vue.set(this.array, startIndex + i, newItems[i]); } ``` 通过手动调用 `Vue.set` 和 `Vue.delete`,你可以确保数组的变化能够触发 Vue.js 的响应式更新。 注意:以上方法适用于 Vue.js 2.x,在 Vue.js 3.x 中,你可以直接使用原生数组方法,因为 Vue.js 3.x 支持了 Proxy 来实现更好的响应式机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值