手写vue2.0源码四之数组响应式

文章类型:Vue

发布者:hp

发布时间:2023-05-25

前面我们已经实现了对象的响应式,在vue中,数组他们采取的是重写函数方法方式

一:定义需要重写的数组方法

/*
保存更改原数组的方法
*/
 
 export var  ARR_METHODS=[
    'push',
    'pop',
    'shift',
    'unshift',
    'splice',
    'sort',
    'reverse'
]

二:针对数组,我们需要重新定义一个实例,来重写数组方法,说白了就是拦截一下,添加自己想要的东西,然后再调用js本省的数组方法

/*
把数组原型的方法和属性给一个新定义的数组方法

*/
var originArrMethods=Array.prototype


/* 
但是这是一个引用类型,找到的还是一个
那么,我们就需要创建一个新的对象,让他们不形成关联
通过Object.create创建对象的原型,继承传递的对象的原型

*/
var arrMethods=Object.create(originArrMethods)

三:接下来就是对方法进行循环遍历,重写,

arrMethods[m]=function(){
  
    /*把参数变成一个数组,类数组变成数组 
    接收到的参数进行自定义的方法
    根据查找规则,如果当前有,则不进行往上查找
    */
    console.log('参数',arguments)
    var args=Array.prototype.slice.call(arguments)
    console.log(args)
    // /**改变this指向,重新去调用 */
  
    /*调用原型上的方法
    实现想要功能,比如push
    通过apply
    传递this 刺this就是调用者  args就是参数
    originArrMethods[m]内置的方法
    */
    var rt=originArrMethods[m].apply(this,args)
    

    /**
     * 重写的目的是不仅能够指向原来的方法,而且还能进行新增的一些列操作
     * 
     * 接下来就是针对数据进行操作
     * 
     * 
     */
    var newArr;

    switch(m){
        case 'push':
        case 'unshift':
            newArr=args
            break
        case 'splice':
            /*下标2表示新增的数据 */
            newArr=args.slice(2)
            break
        default:
            break            

    }
   
    // console.log("rt")
    // console.log(rt)
    /*配合原生方法返回值效果  */
    return rt
}

四:然后就是针对传递进来的值,进行专门方法处理

 /*然后执行数组的操作方法 */
  
    newArr && observeArr(newArr)
    
    
    

五:针对改变的值进行循环处理,又回到观察->观察者->数据上

/**
 * 定义一个专门处理数组的方法
 * 
 */

export default function observeArr(arr){
  
    for (let index = 0; index < arr.length; index++) {
      
       /**观察数据 */
       observe(arr[index])
    }
}

六:针对数组方式,有可能修改的值还是对象或者数组,就需要继续

 /*
    针对对象和数组方式
    采取不一样的方式
    说白了就是不同的处理方式
    */
   if(Array.isArray(data)){
     
    //数组
    data.__proto__=arrMethods;
    //有可能还是数组,那么还需要进行观察
    observeArr(data)
   


   }

七:这样就实现了数组的响应式

vm.list.push(5)
vm.list.splice(2,1,{
    c:1
})
console.log(vm.list)