手写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)