之前写过一篇关于vue3的文章,很多人吐槽:这些API每次用的时候都要引入,感觉有点麻烦。今天我们就来看看vue3相比vue2有什么优势?为什么有人说:自从写了tsvue3,再也回不去vue2了!vue3有什么好?有的人回不去vue2,有的人回不去vue3!1.Vue3的几个新亮点:Performance:性能优化Tree-shaking:支持tree-shaking优化CompositionAPI:组合api新组件:Fragment,Teleport,Supense更好地支持tsCustomRenderAPI:自定义渲染器2.性能改进在性能方面,与vue2相比,vue3有大约1.3到2倍的性能提升。下面我们就来看看它在哪些方面以及如何改进?2.1.响应式性能提升1>diff方法优化diff算法是虚拟DOM技术的必然产物。它将比较新旧DOM,然后在真实DOM上更新更改的DOM。在vue2中,当数据发生变化时,会生成一个新的DOM树,然后与之前的DOM树进行对比,找出不同的节点,然后更新为真正的DOM。比较过程中,不会有变化DOM也会进行比较,会消耗一定的时间。在vue3中,在创建虚拟DOM时,会根据DOM中的内容添加静态标记。当数据发生变化时,会与带有静态标记的节点进行比较,可以快速找到发生变化的DOM。2>事件监听缓存默认情况下,onClick会被视为动态绑定,所以每次都会跟踪它的变化,但是因为是同一个函数,所以不需要跟踪变化,可以直接缓存起来复用3>ssrrendering当静态内容很多的时候,这些内容会以普通字符串的形式push到一个buffer中,即使有动态绑定,也会通过模板插值的方式潜入,这样会比virtualDOM渲染快很多。2.2.在代码量方面,封装尺寸减少了41%。Vue3去掉了一些不常用的API,例如:inline-template、filter等,并使用了tree-shaking。TreeShaking是指当我们导入一个模块时,并不导入这个模块的所有代码,而只导入我们需要的代码。在vue2中,很多函数都是挂载在全局Vue对象上的,比如:nextTick、set函数等,虽然我们不经常用到,但是只要在打包时引入Vue,这些全局函数就会被打包到bundle中。vue3中引入了tree-shaking,通过ES6模块化引入所有API,使得webpack或rollup等打包工具在打包时自动剔除不用的API,最小化bundle体积。初始渲染速度提高55%,更新渲染速度提高133%。元器件按需导入,打包体积更小,项目运行更快更流畅!2.3.编译优化1>静态提升在vue2中,无论元素是否参与更新,每次都会重新创建,然后渲染。vue3使用静态提升后,不参与更新的元素只会被创建一次,渲染时可以直接复用。2>无需在Fragment模板中创建唯一的根节点,直接将标签和内容放在同一层即可。相当于少了一个节点嵌套渲染。3.可选apiVS结合api3.1和vue3的结合api相对更利于维护和打包。3.2.组合后的API高内聚低耦合。使用vue2中可选的API,属性和方法会定义在vue文件的data、methods、watch、computed中,页面逻辑一起处理。多个功能交叉纠缠,代码过于分散。而vue3增加了组合api,将一个功能模块代码聚集在一起,实现高内聚低耦合。提高代码的可读性和可维护性,基于函数组合的API可以更好的复用逻辑代码。组合API和可选API的对比如下:每种颜色代表一个功能。3.3.不应该出现的DOM元素没有问题。vue2中的beforeCreate和created被vue3中的setup函数代替。有的同学有时候在created里面操作DOM元素,有时候会报错,奇怪为什么看不到问题,以至于没有反应。使用setup后,就不容易出现这个问题了。注意:vue3的组合api中的onUnmounted替换了vue2中的beforeDestory。vue3的组合apiunmounted替换了vue2中的destroyed。4.代理比Object.defineProperty有什么优势?proxy和Object.defineProperty都是用来实现响应式数据的。Vue3使用proxy代替vue2的Object.defineProperty效率更高,值得学习。1>Vue2使用Object.defineProperty劫持data数据的getter和setter操作,从而在访问或赋值数据时,动态更新绑定的template模板。但是,Object.defineProperty必须遍历所有的pre-values来劫持每一个property。这个缺点可以通过代理来解决。代理相对于Object.defineProperty的优点如下:代码的执行速度更快。代理可以直接监听一个对象而不是它的属性。代理可以直接监听数组中每个元素的变化。Proxy在初始化的时候不需要遍历所有的属性。如果有多层嵌套,当只访问某个属性时,proxy可以快速访问,而Object.defineProperty也需要遍历所有属性,然后逐层向下访问。代理返回一个新的对象,可以直接操作它来达到目的。而Object.defineProperty是对原始对象进行操作,只能遍历对象属性,直接修改。代理有13个拦截方法,不限于apply、ownKeys、deleteProperty等,但Object.defineporperty没有。2>defineProperty不能监听对象的新属性,不能跟踪数组索引和数组长度的问题,proxy正好解决了这个问题。在vue2中,当我们给一个对象添加一个属性的时候,如果新属性的值发生了变化,我们发现视图并没有更新,因为新属性是监听不到的。同理,如果直接通过下标改变数组,视图也无法更新,因为无法监控。vue3中加入proxy就解决了这些问题。5.更好的ts支持Vue2不适合使用ts,因为它的OptionsAPI风格。options是一个简单的对象,而ts是一个类型系统,面向对象的语法,两者不匹配。Vue3新增了一个defineComponent函数,让ts下的组件更好的使用参数类型推断。如:reactive和ref就很有代表性。6.更高级的组件1>Fragment在vue2中,每个模板必须有一个根节点,否则会报错。vue3中不需要根节点,多个元素或标签可以并排存在。2>传送门。传送中的内容可以添加到任意节点,这对于深度嵌套的组件来说绝对是福音。3>Supense允许程序在等待异步组件的同时渲染一些备份内容,让我们创造流畅的用户体验。总结:vue是目前国内最流行的前端框架之一,vue3在性能和运行速度上的提升要比vue2好很多。简而言之,vue3就是:让项目更快,让代码更少,更容易维护,让我们开发更快,加班更少
