摘要:新版Vue3的概念形成于2018年底,当时Vue2已经两年半了。与一般软件的生命周期相比,这似乎并没有那么长。Vue3于2020年正式上线,源码和API都发生了较大变化,性能有了明显提升,比Vue2.x快了1.2~2倍。本文分享自华为云社区《【云驻共创】vue3 相比 vue2 的十项优点》,作者:海勇。新版本Vue3的概念在2018年末形成,当时Vue2已经诞生两年半。与一般软件的生命周期相比,这似乎并没有那么长。Vue3于2020年正式上线,源码和API都发生了较大变化,性能有了明显提升,比Vue2.x快了1.2~2倍。其中,比较重要的一些优点是:diff算法的优化;hoistStatic静态提升;cacheHandlers事件监听器缓存;ssr渲染;更好的Ts支持;CompositionAPI:组合API/注入API;更高级的组件;自定义渲染API;按需编译,小于vue2.x;支持多根节点组件等。下面详细说说vue3的优点:优点1:diff算法的优化vue2中的虚拟dom是全量比较(每个节点都会逐层比较,是否是hard-codedordynamic,浪费很多时间。有些事件是和静态节点比较的)Vue3在和最后一个虚拟节点比较的时候增加了一个静态标志(patchflag),只比较有patch标志的节点(所在的节点)动态数据位于);通过flag信息可以知道当前节点需要比对的具体内容。例如:下面的模板包含一个div,里面包含三段,前两段是静态固定的,第三段的内容绑定了msg属性。当msg发生变化时,Vue将生成新的虚拟DOM,然后将其与旧的进行比较。
视图更新时,只有动态节点部分进行diff操作,减少资源消耗。Patchflag是一个枚举。值为1表示该元素的文本是动态绑定的,值为2表示该元素的类是动态绑定的。优势二:hoistStatic静态提升vue2不管元素是否参与更新,每次都会重新创建然后渲染。Vue3会对不参与更新的元素做静态提升,只会创建一次,渲染时可以直接复用。例如:下面我们使用Vue3TemplateExplorer直观感受一下:
beforestaticpromotionexportfunctionrender(...){return(_openBlock(),_createBlock('div',null,[_createVNode('div',null,'co-creation1'),_createVNode('div',null,'Create2'),_createVNode('div',null,_toDisplayString(_ctx.name),1/*TEXT*/),]))}静态提升后const_hoisted_1=/*#__PURE__*/_createVNode('div',null,'Create1',-1/*HOISTED*/)const_hoisted_2=/*#__PURE__*/_createVNode('div',null,'Create2',-1/*HOISTED*/)导出函数render(...){return(_openBlock(),_createBlock('div',null,[_hoisted_1,_hoisted_2,_createVNode('div',null,_toDisplayString(_ctx.name),1/*TEXT*/),]))}从上面的代码我们可以看出_hoisted_1和_hoisted_2这两个方法在渲染函数render之外被提升了,也就是我们所说的静态提升通过静态提升,可以避免每次渲染都重新创建这些对象,从而大大提高渲染效率。优势三:cacheHandlers事件监听缓存在vue2.x中,每次触发绑定事件,都要重新生成一个新的函数来更新。cacheHandlers是Vue3中提供的事件缓存对象。当启用cacheHandlers时,会自动生成一个内联函数,同时生成一个静态节点。当事件再次触发时,只需要从缓存中调用它而不需要再次更新它。默认情况下,onClick会被视为动态绑定,所以每次都会跟踪它的变化,但是同一个函数不需要跟踪变化,可以直接缓存起来复用。例如:下面我们同样使用Vue3TemplateExplorer来查看事件监听缓存的作用:
这段html之后编译,就变成了我们下面的结构(没有开启事件监听缓存):.todo},'Dosomethinginteresting',8/*PROPS*/,['onClick']),]))}当我们启用事件侦听器缓存时:exportfunctionrender(...){return(_openBlock(),_createBlock('div',null,[_createVNode('div',{onClick://开启后监听_cache[1]||(_cache[1]=(...args)=>_ctx.todo(...args)),},'dosomethinginteresting'),]))}我们可以对比一下启用事件监听缓存前后的代码,以及转换后的代码,你可能看不懂,但没关系,我们只需要观察是否有静电标记即可。在Vue3的diff算法中,只有带有静态标记的才会被比较跟踪。优势四:ssr渲染Vue2也有SSR渲染,但是和Vue2相比,Vue3中的SSR渲染在性能上也有相应的提升。当有大量静态内容时,内容会作为普通字符串被推入缓冲区,即使有动态绑定,也会通过模板插值潜入。这将比通过虚拟dmo渲染快得多。当静态内容足够大时,会在客户端使用_createStaticVNode方法生成一个静态节点。这些静态节点会直接innerHtml,所以不需要创建对象,然后根据对象渲染。优势五:更好的Ts支持Vue2由于vue2的OptionAPI风格,不适合使用ts。options是一个简单的对象,而ts是一个类型系统,面向对象的语法。两者有点不匹配。在结合vue2和ts的具体实践中,我们需要使用vue-class-component加强vue组件,让脚本支持TypeScript装饰器,使用vue-property-decorator添加更多结合Vue特性的装饰器,最后创建ts组件写法和js组件的写法有很大区别。vue3中特制了defineComponent函数,让组件在ts下更好的使用参数类型推断。在CompositionAPI代码风格中,比较有代表性的API是ref和reactive,它们也很好地支持类型声明。import{defineComponent,ref}from'vue'constComponent=defineComponent({props:{success:{type:String},student:{type:ObjectasPropType
,required:true}},setup(){constyear=ref(2020)constmonth=ref('9')month.value=9//OKconstresult=year.value.split('')}优势六:CompostionAPI:CompositionAPI/传统注入API的网页是html/css/javascript(结构/样式/逻辑)分离的,Vue通过组件化将紧密相关的结构/样式/逻辑放在一起,有利于代码维护。Compositionapi更进一步,专注于JS(逻辑)部分,将逻辑相关的代码放在一起,更有利于代码维护。在vue2的组件中使用了OptionAPI风格(data/methods/mounted)组织的代码,会造成逻辑分散。比如我们完成一个计数器函数,需要在data中声明变量,在methods函数中定义response函数,在mounted中初始化变量。如果要在一个功能多、代码量大的组件中维护这样的功能,需要反复切换到data/methods/mounted中对应的位置,然后进行代码修改。在vue3中,使用setup函数。如下图,count相关的逻辑放在counter.js文件中,todo相关的逻辑放在todos.js中。从'./counter'导入useCounter从'./todos'setup(){let{val,todos,addTodo}=useTodo()let{count,add}=useCounter()return{val,todos,addTodo,count,add,}优点七:更高级的组件vue2??是不允许这样写的,组件必须有根节点,现在可以这样写,vue会为我们创建一个虚拟的Fragment节点。HUAWEICloudSharingExpert
Full-stackBlogger
在Suspended-component完全渲染之前,会显示alternatecontent。如果是异步组件,Suspense可以等待组件下载完成,或者在setup函数中进行一些异步操作。优势八:自定义渲染APIvue2.x的项目架构对于weex(跨平台移动解决方案)、myvue(小程序上使用)等不同平台的渲染不是很友好。Vue3.0推出了自定义渲染API来解决这个问题。我们先来看看vue2和vue3的入口写法的区别。vue2importVuefrom'vue'importAppfrom'./App.vue'newVue({=>h(App)}).$mount('#app')vue3const{createApp}from'vue'importAppfrom"./src/App"createApp(App).mount(('#app')Vue官方实现的createApp会为我们的模板映射生成html代码,但是如果你不想渲染成html,而是渲染到canvas时该类不是html代码,需要使用CustomRendererAPI定义自己的render渲染生成函数import{createApp}from"./runtime-render";importAppfrom"./src/App";//根组件createApp(App).mount('#app');使用自定义渲染API,完美解决了weex、myvue等解决方案的问题,重写createApp即可。优点九:按需编译,体积比vue2.x小框架的大小也会影响它的性能,这是web应用程序唯一关心的,因为资源需要即时下载,而应用程序只有在浏览器解析nec后才能交互essaryjavascript对于单页应用程序尤其如此。尽管Vue一直比较轻量级(Vue2的压缩运行时大小为23KB)。在Vue3中,通过将大部分全局API和内部帮助程序移动到ES模块导出来实现这一目标。这使现代打包工具能够静态分析模块依赖关系并删除未使用的与导出相关的代码。模板编译器还会生成友好的Tree-shaking代码,这些代码在模板中实际使用。此功能的帮助程序仅在启用该功能时导入。框架的某些部分永远不会进行Tree-shaking,因为它们对于任何类型的应用程序都是必不可少的。我们称这些基本部分的指标为基本尺寸。尽管添加了许多新功能,但Vue3的基本大小压缩后约为10KB,不到Vue2大小的一半。优势十:支持多根节点组件Vue3一个模板不再局限于有多个根节点,(Attributeinheritanceonmultiplerootnodes)需要明确定义属性应该分布在哪里。否则,控制台会给出警告提示。在Vue3中,组件现在正式支持多根节点组件,也就是片段!在2.x中,不支持多根组件,当用户不小心创建多根组件时会发出警告,因此,为了修复此错误,将多个组件封装在一个组件中。以下...
在3.x,组件现在可以有多个根节点!但是,这确实需要开发人员明确定义属性应分布在何处。...Vue在最后吧是国内最火的前端框架之一。性能提升,运行速度是vue2的1.2-2倍。体积更小,按需编译vue2体积更小。类型推断,更好地支持ts也是一个趋势。高级授权,公开低级API并提供更高级的内置组件。组合API可以更好的组织逻辑,封装逻辑,复用逻辑。未来展望:技术永远更新更好,升级vue3的公司越来越多;大型项目对TS越来越友好大型项目可以使用vue3;作为程序员,我们应该适应市场,提高自己的竞争力,提供加薪空间。点击关注,第一时间了解华为云的新鲜技术~