加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

茶余饭后聊聊 Vue3.0 响应式数据那些事儿

发布时间:2019-10-31 12:00:23 所属栏目:建站 来源:佚名
导读:别再更新了,实在是学不动了这句话道出了多少前端开发者的心声,不幸的是 Vue 的作者在国庆区间发布了 Vue3.0 的 pre-Aplha 版本,这意味着 Vue3.0 快要和我们见面了。既来之则安之,扶我起来我要开始讲了。Vue3.0 为了达到更快、更

Vue2.x 中被大家吐槽的最多的一点就是针对数组只实现了 push,pop,shift,unshift,splice,sort,reverse' 这七个方法的监听,以前通过数组下标改变值的时候,是不能触发视图更新的。这里插一个题外话,很多人认为 Vue2.x 中数组不能实现全方位监听是 Object.defineProperty 不能监听数组下标的改变,这可就冤枉人家了,人家也能侦听数组下标变化的好吗,不信你看

  1. const arr = ["2019","云","栖","音","乐","节"]; 
  2. arr.forEach((val,index)=>{ 
  3.     Object.defineProperty(arr,index,{ 
  4.         set(newVal){ 
  5.             console.log("赋值"); 
  6.         }, 
  7.         get(){ 
  8.             console.log("取值"); 
  9.             return val; 
  10.         } 
  11.     }) 
  12. }) 
  13. let index = arr[1]; 
  14. //取值 
  15. arr[0] = "2050"; 
  16. //赋值 

没毛病,一切变化都在人家的掌握中。上面这段代码,有没有人没看懂,我假装你们都不懂,贴张图

茶余饭后聊聊 Vue3.0 响应式数据那些事儿

从数组的数据结构来看,数组也是一个 Key-Value 的键值对集合,只是 Key 是数字罢了,自然也可以通过Object.defineProperty 来实现数组的下标访问和赋值拦截了。其实 Vue2.x 没有实现数组的全方位监听主要有两方面原因:

数组和普通对象相比,JS 数组太"多变"了。比如: arr.length=0 ,可以瞬间清空一个数组; arr[100]=1 又可以瞬间将一个数组的长度变为 100(其他位置用空元素填充),等等骚操作。对于一个普通对象,我们一般只会改变 Key 对应的 Value 值,而不会连key都改变了,而数组就不一样了 Key 和 Value 都经常增加或减少,因此每次变化后我们都需要重新将整个数组的所有 key 递归的使用 Object.defineProperty 加上 setter 和 getter,同时我们还要穷举每一种数组变化的可能,这样势必就会带来性能开销问题,有的人会觉得这点性能开销算个 x 呀,但是性能问题都是由小变大的,如果数组中存的数据量大而且操作频繁时,这就会是一个大问题。React16.x 在就因为在优化 textNode 的时候,移除了无意义的 span 标签,性能据说都提升了多少个百分点,所以性能问题不可小看。

数组在应用中经常会被操作,但是通常 push,pop,shift,unshift,splice,sort,reverse 这 7 种操作就能达到目的。因此,出于性能方面的考虑 Vue2.x 做出了一定的取舍。

那么 Vue3.0 怎么又走回头路去实现了数组的全面监听了呢?答案就是 Proxy 和 Reflet 这一对原生 CP 的出现,Vue3.0 使用 Proxy 作为响应式数据实现的核心,用 Proxy 返回一个代理对象,通过代理对象来收集依赖和触发更新。大概的原理像这段代码一样:

  1. const arr = ["2019","云","栖","音","乐","节"]; 
  2. let ProxyArray = new Proxy(arr,{ 
  3.     get:function(target, name, value, receiver) { 
  4.         console.log("取值") 
  5.         return Reflect.get(target,name); 
  6.     }, 
  7.     set: function(target, name, value, receiver) { 
  8.        console.log("赋值") 
  9.        Reflect.set(target,name, value, receiver);; 
  10.     } 
  11.  }) 
  12.  const index = ProxyArray[0]; 
  13.  //取值 
  14.  ProxyArray[0]="2050" 
  15.  //赋值 

效果和 Object.defineProperty 一样一样的,又显得清新脱俗有没有?而且 Proxy 只要是对象都能代理,后面还会提到。当然 Vue3.0 是虽然有了新欢,但也没忘记旧爱,对于在之前版本中数组的几种方法的监听还是照样支持的。

惰性监听

什么是"惰性监听"?

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读