当前位置: 首页 > Web前端 > vue.js

Vue3.0时代你必须知道的:响应式原则

时间:2023-04-01 10:39:23 vue.js

Vue3.0时代你必须知道的:响应式原则Vue3.0发布了,更新了一系列的东西,包括替换"""Object.defineProperty""。今天我们切入正题,直接说说响应式新样式的原理和优势。回顾一下Vue2.x响应式原理的核心API---Object.defineProperty()1.Object.defineProperty()语法说明Object.defineProperty()的作用是直接在一个对象上定义一个新的属性,或者修改一个已经存在的属性Object.defineProperty(obj,prop,desc)obj当前需要定义其属性的对象prop当前要定义的属性名desc属性描述符letPerson={}lettemp=nullObject.defineProperty(Person,'name',{get:function(){returntemp},set:function(val){temp=val}})console.log(Person.name)//get()Person.name='B'//set()在上面的代码中我们可以看出Object.defineProperty()的用法是为一个对象定义一个属性(方法),并提供set和get两种内部实现,这样我们就可以获取或设置这个属性(方法)的响应式原理vue2.x就是利用这个API来监控拦截数据的读取和赋值。但是有一个地方吐槽最多:Vue2.x只实现了对数组的push、pop、shift、unshift、splice、sort、reverse这七种方法的监听。通过数组下标改变值时,无法触发视图更新。但是并不是因为Object.defineProperty()不能监听数组下标,因为数组也是一种对象,只是每个key都是一个数字。之所以出现以上情况,主要是因为:数组的可变性。数组可以通过下标直接操作数组的长度,比如Array.length=0;数组会瞬间清空,Array.length=100,瞬间将100个空元素填充到数组中。也就是说,数组的key和value都有可能发生变化。一旦数组下标发生变化,就需要再次递归遍历数组,使用Object.defineProperty加上setter和getter,在性能上很不友好。有许多方法可以操作数组。但通常push、pop、shift、unshift、splice、sort、reverse这七个操作就可以达到目的。因此,出于性能的考虑,Vue2.x做了一定的取舍。proxy""syntax""constp=newProxy(target,handler)""target""用Proxy包装的目标对象(可以是任何类型的对象,包括本机数组、函数,甚至是另一个代理)。“handler”是一个对象,通常具有函数作为属性,每个属性中的函数定义了代理p执行各种操作时的行为。Vue3.0使用Proxy直接监听数据的各种自定义行为,无需遍历Object.defineProperty。上面代码constarr=["2019","cloud","qi","sound","music","section"];让ProxyArray=newProxy(arr,{get:function(target,name,value,receiver){console.log("value")returnReflect.get(target,name);},set:function(target,name,value,receiver){console.log("assignment")Reflect.set(target,name,value,receiver);;}})constindex=ProxyArray[0];//ValueProxyArray[0]="2050"//给上面的代码赋值,实现了和Object.defineProperty一样的效果,去掉了遍历对象的操作,在性能上可以说是大大优化了,看起来一目了然。只要是对象,Proxy就可以充当代理。Vue3.0Responsive的优点那么,除了上面提到的可以直接监听数组变化的优点之外,还有哪些优点呢?选择性监控Vue3.0将响应式类型单独分离出来,直接暴露给用户,包括ref,reactiveimport{ref,reactive}fromVuesetup(){constcount=ref(0)constperson=reactive({name:'小红'})}在Vue3.0中,我们会通过ref和reactive来生成响应式数据,也就是说Vue把选择权交给了用户。我们会选择性地对所需数据做出“回应”。与Vue2.x相比,模板中使用的所有数据都需要在data中定义。当组件实例被初始化时,整个数据对象将变成一个可观察对象。在这种情况下,组件的实例化速度显然会变慢,需要分配一部分运行内存来保存这种冗余的“响应式”数据。所以Vue3.0的响应式不仅“提高了组件实例的初始化速度”,而且“减少了运行内存的使用”。IE浏览器呢?这是一个我实在不想提却又避不开的话题。IE在前端开发者眼中无异于魔鬼。在Vue3.0之前,响应式数据的实现依赖于ES5的Object.defineProperty,所??以只要支持ES5的浏览器都支持Vue,也就是说Vue2.x可以支持IE9。Vue3.0依赖Proxy和Reflect这对新时代诞生的CP,无法翻译成ES5,也无法通过Polyfill提供兼容性,尴尬。根据开发者在技术战线获悉的信息,正式版会在正式版发布前兼容IE11。至于低版本的IE,就只有爽歌了。其实不用太担心IE,因为连微软自己都已经放弃对待IE转而拥抱Chromium了,我们何必纠结呢?欢迎关注公众号:前端日常博客本文采用mdnice排版