vue数组响应式原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue数组响应式原理相关的知识,希望对你有一定的参考价值。

参考技术A vue2中Object.defineProperty响应式只对对象有效,对数组无效,所以对数组做额外处理。我们知道,会改变数组本身的方法只有7个:sort, push, pop, slice, splice, shift, unshift,所以可以通过重写这些方法来达到数组响应式

解决方案:

1. 找到数组原型

2. 覆盖那些能够修改数组的更新方法,让他们在修改数组同时,还可以通知更新

3. 将得到的新的原型设置到数组实例原型上

4. 对数组内部元素实现响应式

// 实现数组响应式// 1. 替换数组原型中7个方法constoriginalProto=Array.prototype// 克隆体原数组原型constarrayProto=Object.create(originalProto)// 可修改数组的7个方法 , 'sort'constchangeMethods=['push','pop','shift','unshift','slice','splice','sort']//  2. 在克隆的原型上,覆盖那些能够修改数组的更新方法,让他们在修改数组同时,还可以通知更新changeMethods.forEach(method=>arrayProto[method]=function()// 进行原始操作originalProto[method].apply(this,arguments)// 覆盖操作:增加更新通知console.log(`数组正在执行$method方法`);)// 对象响应化functiondefineReactive(obj,key,value)Object.defineProperty(obj,key,get()console.log('获取'+key);returnvalue,set(newVal)if(newVal!==value)// console.log(newVal);// console.log(JSON.stringify(obj[key]));console.log(`正在改变$key值:从$obj[key]变为$newVal`)value=newVal)functionobserver(obj)// 不是对象或者为null,不做响应式,结束if(typeofobj!=='object'||obj===null)return;// 如果是数组,修改其实例的原型if(Array.isArray(obj))// 3. 将得到的新的原型设置到数组实例原型上obj.__proto__=arrayProto// 4. 对数组内的元素,同样进行响应化for(leti=0;i<obj.length;i++)// console.log(obj[i]);observer(obj[i])// 如果是对象elseObject.keys(obj).forEach(key=>console.log(obj,key,obj[key]);defineReactive(obj,key,obj[key]))obj=[a:1,2,7,5,3]observer(obj)obj.push(4)// 数组正在执行push方法obj.pop()// 数组正在执行pop方法obj[0].a=2// 获取a    // 正在改变a值:从1变为2obj.sort()// 数组正在执行sort方法console.log(obj);// [ 2, 3, 5, 7, a: [Getter/Setter] ]console.log(obj[4].a);// 获取a  // 2

链接:https://www.jianshu.com/p/886ac356c13d

以上是关于vue数组响应式原理的主要内容,如果未能解决你的问题,请参考以下文章

Proxy(vue响应式原理:数据侦测--数据劫持和数据代理)

vue 数组 新增元素 响应式原理

聊一聊 Vue3 中响应式原理

vue数组和对象的响应式实现

vue2数据响应式原理

Vue响应式原理/双向数据绑定