摘要:Vue3 新版本的理念成型于 2018 年末,过后的 Vue 2 曾经有两岁半了。比起通用软件的生命周期来这如同也没那么久,Vue3 在 2020 年正式推出,在源码和 API 都有较大变动,性能失去了显著的晋升,比 Vue2.x 快 1.2~2 倍。
本文分享自华为云社区《【云驻共创】vue3 相比 vue2 的十项长处》,作者:海拥。
Vue3 新版本的理念成型于 2018 年末,过后的 Vue 2 曾经有两岁半了。比起通用软件的生命周期来这如同也没那么久,Vue3 在 2020 年正式推出,在源码和 API 都有较大变动,性能失去了显著的晋升,比 Vue2.x 快 1.2~2 倍。
其中,一些比拟重要的长处有:
diff 算法的优化;hoistStatic 动态晋升;cacheHandlers 事件侦听器缓存;ssr 渲染;更好的 Ts 反对;Compostion API: 组合 API/ 注入 API;更先进的组件;自定义渲染 API;按需编译,体积比 vue2.x 更小;反对多根节点组件等。上面咱们就来具体说说 vue3 的长处:
长处 1:diff 算法的优化
vue2 中的虚构 dom 是全量的比照(每个节点不管写死的还是动静的都会一层一层比拟,这就节约了大部分事件在比照动态节点上)
vue3 新增了动态标记(patchflag)与上次虚构节点比照时,只比照带有 patch flag 的节点(动态数据所在的节点);可通过 flag 信息得悉以后节点要比照的具体内容。
例如:上面的模板蕴含一个 div,div 内蕴含三个段落,其中前两个段落是动态固定不变的,而第三个段落的内容绑定的 msg 属性,当 msg 扭转的时候,Vue 会生成新的虚构 DOM 而后和旧的进行比照。
<div>
<p> 云驻共创 </p>
<p> 如何评估 vue3</p>
<p>{{msg}}</p>
</div>
当视图更新时,只对动静节点局部进行 diff 运算,缩小了资源的损耗。Patchflag 是个枚举,取值为 1 代表这个元素的文本是动静绑定的,取值为 2 代表元素的 class 是动静绑定的。
长处 2:hoistStatic 动态晋升
vue2 无论元素是否参加更新,每次都会从新创立而后再渲染。
vue3 对于不参加更新的元素,会做动态晋升,只会被创立一次,在渲染时间接复用即可。
例如:上面咱们利用 Vue 3 Template Explorer, 来直观的感受一下:
<div>
<div> 共创 1 </div>
<div> 共创 2 </div>
<div>{{name}}</div>
</div>
动态晋升之前
export function render(...) {
return (_openBlock(),
_createBlock('div', null, [_createVNode('div', null, '共创 1'),
_createVNode('div', null, '共创 2'),
_createVNode(
'div',
null,
_toDisplayString(_ctx.name),
1 /* TEXT */
),
])
)
}
动态晋升之后
const _hoisted_1 = /*#__PURE__*/ _createVNode(
'div',
null,
'共创 1',
-1 /* HOISTED */
)
const _hoisted_2 = /*#__PURE__*/ _createVNode(
'div',
null,
'共创 2',
-1 /* HOISTED */
)
export function render(...) {
return (_openBlock(),
_createBlock('div', null, [
_hoisted_1,
_hoisted_2,
_createVNode(
'div',
null,
_toDisplayString(_ctx.name),
1 /* TEXT */
),
])
)
}
从以上代码中咱们能够看出,_hoisted_1 和_hoisted_2 两个办法被晋升到了渲染函数 render 之外,也就是咱们说的动态晋升。通过动态晋升能够防止每次渲染的时候都要从新创立这些对象,从而大大提高了渲染效率。
长处 3:cacheHandlers 事件侦听器缓存
vue2.x 中,绑定事件每次触发都要从新生成全新的 function 去更新,cacheHandlers 是 Vue3 中提供的事件缓存对象,当 cacheHandlers 开启,会主动生成一个内联函数,同时生成一个动态节点。当事件再次触发时,只需从缓存中调用即可,无需再次更新。
默认状况下 onClick 会被视为动静绑定,所以每次都会追踪它的变动,然而同一个函数没必要追踪变动,间接缓存起来复用即可。
例如:上面咱们同样是通过 Vue 3 Template Explorer,来看一下事件监听器缓存的作用:
<div>
<div @click="todo"> 做点乏味的事 </div>
</div>
该段 html 通过编译后变成咱们上面的构造(未开启事件监听缓存):
export function render(...) {return (_openBlock(),_createBlock('div', null, [_createVNode('div',{ onClick: _ctx.todo}, '做点乏味的事', 8 /* PROPS */,
['onClick']),
])
)
}
当咱们开启事件监听器缓存后:
export function render(...) {return (_openBlock(),_createBlock('div', null, [
_createVNode('div',{
onClick: // 开启监听后
_cache[1] || (_cache[1] = (...args) =>_ctx.todo(...args)),
},'做点乏味的事'),
])
)
}
咱们能够比照开启事件监听缓存前后的代码,转换之后的代码, 大家可能还看不懂, 然而不要紧,咱们只须要察看有没有动态标记即可,在 Vue3 的 diff 算法中, 只有有动态标记的才会进行比拟, 才会进行追踪。
长处 4:ssr 渲染
Vue2 中也是有 SSR 渲染的,然而 Vue3 中的 SSR 渲染绝对于 Vue2 来说,性能方面也有对应的晋升。
当存在大量动态内容时,这些内容会被当作纯字符串推动一个 buffer 外面,即便存在动静的绑定,会通过模版插值潜入进去。这样会比通过虚构 dmo 来渲染的快上很多。
当动态内容大到一个量级的时候,会用_createStaticVNode 办法在客户端去生成一个 static node,这些动态 node,会被间接 innerHtml,就不须要再创建对象,而后依据对象渲染。
长处 5:更好的 Ts 反对
vue2 不适宜应用 ts,起因在于 vue2 的 Option API 格调。options 是个简略对象,而 ts 是一种类型零碎、面向对象的语法。两者有点不匹配。
在 vue2 联合 ts 的具体实际中,要用 vue-class-component 强化 vue 组件,让 Script 反对 TypeScript 装璜器,用 vue-property-decorator 来减少更多联合 Vue 个性的装璜器,最终搞的 ts 的组件写法和 js 的组件写法差异挺大。
在 vue3 中,量身打造了 defineComponent 函数,使组件在 ts 下,更好的利用参数类型推断。Composition API 代码格调中,比拟有代表性的 api 就是 ref 和 reactive,也很好的反对了类型申明。
import {defineComponent, ref} from 'vue'
const Component = defineComponent({
props: {success: { type: String},
student: {
type: Object as PropType<Student>,
required: true
}
},
setup() {const year = ref(2020)
const month = ref<string | number>('9')
month.value = 9 // OK
const result = year.value.split('')
}
长处 6:Compostion API: 组合 API/ 注入 API
传统的网页是 html/css/javascript(构造 / 款式 / 逻辑)拆散。vue 通过组件化的形式,将分割严密的构造 / 款式 / 逻辑放在一起,有利于代码的保护。compostion api 更进一步,着力于 JS(逻辑)局部,将逻辑相干的代码放在一起,这样更有利于代码的保护。
在 vue2 的组件内应用的是 Option API 格调 (data/methods/mounted) 来组织的代码,这样会让逻辑扩散,举个例子就是咱们实现一个计数器性能,要在 data 里申明变量,在 methods 定义响应函数,在 mounted 里初始化变量,如果在一个性能比拟多、代码量比拟大的组件里,你要保护这样一个性能,就须要在 data/methods/mounted 重复的切换到对应地位,而后进行代码的更改。
而在 vue3 中,应用 setup 函数。如下所示跟 count 相干的逻辑,都放到 counter.js 文件里,跟 todo 相干的逻辑放到 todos.js 里。
import useCounter from './counter'
import useTodo from './todos'
setup(){let { val, todos, addTodo} = useTodo()
let {count,add} = useCounter()
return {
val, todos, addTodo,
count,add,
}
长处 7:更先进的组件
vue2 是不容许这样写的,组件必须有一个跟节点,当初能够这样写,vue 将为咱们创立一个虚构的 Fragment 节点。
<template>
<div> 华为云享专家 </div>
<div> 全栈畛域博主 </div>
</template>
在 Suspended-component 齐全渲染之前,备用内容会被显示进去。如果是异步组件,Suspense 能够期待组件被下载,或者在设置函数中执行一些异步操作。
长处 8:自定义渲染 API
vue2.x 我的项目架构对于 weex(挪动端跨平台计划)和 myvue(小程序上应用)等渲染到不同平台不太敌对,vue3.0 推出了自定义渲染 API 解决了该问题。上面咱们先看 vue2 和 vue3 的入口写法有哪些不同。
vue2
import Vue from 'vue'
import App from './App.vue'
new Vue({=> h(App)}).$mount('#app')
vue3
const {createApp} from 'vue'
import App from "./src/App"
createApp(App).mount(('#app')
vue 官网实现的 createApp 会给咱们的 template 映射生成 html 代码,然而要是你不想渲染生成到 html,而是要渲染生成到 canvas 之类的不是 html 的代码的时候,那就须要用到 Custom Renderer API 来定义本人的 render 渲染生成函数了。
import {createApp} from "./runtime-render";
import App from "./src/App"; // 根组件
createApp(App).mount('#app');
应用自定义渲染 API,如 weex 和 myvue 这类计划的问题就失去了完满解决。只需重写 createApp 即可。
长处 9:按需编译,体积比 vue2.x 更小
框架的大小也会影响其性能。这是 Web 应用程序的惟一关注点,因为须要即时下载资源,在浏览器解析必要的 JavaScript 之前该应用程序是不可交互的。对于单页应用程序尤其如此。只管 Vue 始终是绝对轻量级的(Vue 2 的运行时大小压缩为 23 KB)。
在 Vue 3 中,通过将大多数全局 API 和外部帮忙程序移至 ES 模块导出来,实现了这一指标。这使古代的打包工具能够动态剖析模块依赖性并删除未应用的导出相干的代码。模板编译器还会生成敌对的 Tree-shaking 代码,在模板中理论应用了该性能时才导入该性能的帮忙程序。
框架的某些局部永远不会 Tree-shaking,因为它们对于任何类型的利用都是必不可少的。咱们将这些必不可少的局部的度量规范称为基准尺寸。只管减少了许多新性能,但 Vue 3 的基准大小压缩后约为 10 KB,还不到 Vue 2 的一半。
长处 10:反对多根节点组件
Vue3 一个模板不再限度有多个根节点,(多个根节点上的 Attribute 继承) 须要显式定义 attribute 应该散布在哪里。否则控制台会给出正告提醒。
在 Vue 3 中,组件当初正式反对多根节点组件,即片段!
在 2.x 中,不反对多根组件,当用户意外创立多根组件时会收回正告,因而,为了修复此谬误,许多组件被包装在一个中。如下
<template>
<div>
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
</template>
在 3.x 中,组件当初能够有多个根节点!然而,这的确要求开发者明确定义属性应该散布在哪里。
<template>
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
</template>
结尾想说的
Vue 是国内最火的前端框架之一。性能晋升,运行速度是 vue2 的 1.2- 2 倍。
体积更小,按需编译体积 vue2 要更小。
类型推断,更好的反对 ts 这个也是趋势。
高级给予,裸露了更底层的 API 和提供更先进的内置组件。
组合 API,可能更好的组织逻辑,封装逻辑,复用逻辑
对将来的瞻望:
技术总是越新越好,越来越多的企业都降级了 vue3;
大型项目,因为对 TS 的敌对越来越多的大型项目能够应用 vue3;
作为程序员,咱们就应该适应市场,进步本人的竞争力,为加薪提供空间。
点击关注,第一工夫理解华为云陈腐技术~