手撕Vue源码(三)数组数据劫持

4 篇文章 0 订阅
  • 我们在建立观察者的时候,没有考虑数据是数组的情况,如果数据是数组,按照之前的逻辑,会将数组以索引为属性名进行劫持,这样对性能并不高,我们不考虑对数组索引进行劫持,而只封装数组的方法
    • 建立观察者时,添加对数组的判断
      • 若为数组,则分流进行下一步操作
        • 重建数组父类,重新添加数组方法
        • 若数组里面的值为对象,则应该监听
          • 遍历数组,对值调用观察者
        • 数组可以通过封装的方法来追加对象,应该对追加的内容进行监听
          • 在数组上追加属性,指向观察者实例
          • 判断数组追加内容,通过该属性,调用观察者
  • 观察者类更改
  •  constructor(data){
            // data.__po__ = this;
            Object.defineProperty(data,'__po__',{
                value:this,
                enumerable:false
            })
            if(Array.isArray(data)){
                data.__proto__ = arrayMethods;
                this.observeArray(data);
            }
            else {
            //对对象中的所有属性进行劫持
            this.walk(data);
            }
        }
        // 如果数组中包含对象,则再次被监控
        observeArray(data){
            data.forEach(item =>{
                observe(data);
            })
        }

    新建arrat.js

  • let oldArrayPrototype = Array.prototype;
    export let arrayMethods = Object.create(oldArrayPrototype);
    let methods = [
        'push',
        'shift',
        'unshift',
        'pop',
        'reverse',
        'sort',
        'splice'
    ]
    
    methods.forEach(method =>{
        arrayMethods[method] = function(...args){
            console.log('数组改变了');
            oldArrayPrototype[method].call(this,...args);
            // 通过push、unshift、splice方法也可能对数据进行更改
            let po = this.__po__;
            let inserted;
            switch (method) {
                case 'push':
                case 'unshift':
                    inserted = args;
                    break;
                case 'splice':
                    inserted = args.slice(2);
                    break;
            }
            if(inserted) {
                po.observeArray(inserted);
            }
        }
    })

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问也去

创作不易,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值