vue3 與 vue2 優(yōu)點對比匯總
摘要:
Vue3新版本的理念成型于 2018 年末,當時的 Vue 2 已經有兩歲半了。比起通用軟件的生命周期來這好像也沒那么久,Vue3在2020年正式推出,在源碼和API都有較大變化,性能得到了顯著的提升,比Vue2.x快1.2~2倍。
Vue3新版本的理念成型于 2018 年末,當時的 Vue 2 已經有兩歲半了。比起通用軟件的生命周期來這好像也沒那么久,Vue3在2020年正式推出,在源碼和API都有較大變化,性能得到了顯著的提升,比Vue2.x快1.2~2倍。
其中,一些比較重要的優(yōu)點有:
diff算法的優(yōu)化:hoistStatic 靜態(tài)提升;cacheHandlers事件偵聽器緩存;ssr渲染;更好的Ts支持;Compostion API: 組合API/注入API;更先進的組件;自定義渲染API;按需編譯,體積比vue2.x更小;支持多根節(jié)點組件等。
下面我們就來具體說說vue3 的優(yōu)點:
優(yōu)點1:diff算法的優(yōu)化
vue2中的虛擬dom是全量的對比(每個節(jié)點不論寫死的還是動態(tài)的都會一層一層比較,這就浪費了大部分事件在對比靜態(tài)節(jié)點上)
vue3新增了靜態(tài)標記(patchflag)與上次虛擬節(jié)點對比時,只對比帶有patch flag的節(jié)點(動態(tài)數(shù)據(jù)所在的節(jié)點);可通過flag信息得知當前節(jié)點要對比的具體內容。
例如:下面的模板包含一個div,div內包含三個段落,其中前兩個段落是靜態(tài)固定不變的,而第三個段落的內容綁定的msg屬性,當msg改變的時候,Vue會生成新的虛擬DOM然后和舊的進行對比。
<div>
<p>云駐共創(chuàng)</p>
<p>如何評價 vue3</p>
<p>{{msg}}</p>
</div>
當視圖更新時,只對動態(tài)節(jié)點部分進行diff運算,減少了資源的損耗。Patchflag是個枚舉,取值為1代表這個元素的文本是動態(tài)綁定的,取值為2代表元素的class是動態(tài)綁定的。
優(yōu)點2:hoistStatic 靜態(tài)提升
vue2無論元素是否參與更新,每次都會重新創(chuàng)建然后再渲染。vue3對于不參與更新的元素,會做靜態(tài)提升,只會被創(chuàng)建一次,在渲染時直接復用即可。例如:下面我們利用Vue 3 Template Explorer,來直觀的感受一下:
<div>
<div>共創(chuàng)1</div>
<div>共創(chuàng)2</div>
<div>{{name}}</div>
</div>
靜態(tài)提升之前
export function render(...) {
return (
_openBlock(),
_createBlock('div', null, [
_createVNode('div', null, '共創(chuàng)1'),
_createVNode('div', null, '共創(chuàng)2'),
_createVNode(
'div',
null,
_toDisplayString(_ctx.name),
1 /* TEXT */
),
])
)
}
靜態(tài)提升之后
const _hoisted_1 = /*#__PURE__*/ _createVNode(
'div',
null,
'共創(chuàng)1',
-1 /* HOISTED */
)
const _hoisted_2 = /*#__PURE__*/ _createVNode(
'div',
null,
'共創(chuàng)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兩個方法被提升到了渲染函數(shù) render 之外,也就是我們說的靜態(tài)提升。通過靜態(tài)提升可以避免每次渲染的時候都要重新創(chuàng)建這些對象,從而大大提高了渲染效率。
優(yōu)點3:cacheHandlers 事件偵聽器緩存
vue2.x中,綁定事件每次觸發(fā)都要重新生成全新的function去更新,cacheHandlers 是Vue3中提供的事件緩存對象,當 cacheHandlers 開啟,會自動生成一個內聯(lián)函數(shù),同時生成一個靜態(tài)節(jié)點。當事件再次觸發(fā)時,只需從緩存中調用即可,無需再次更新。
默認情況下onClick會被視為動態(tài)綁定,所以每次都會追蹤它的變化,但是同一個函數(shù)沒必要追蹤變化,直接緩存起來復用即可。
例如:下面我們同樣是通過Vue 3 Template Explorer,來看一下事件監(jiān)聽器緩存的作用:
<div>
<div @click="todo">做點有趣的事</div>
</div>
該段 html 經過編譯后變成我們下面的結構(未開啟事件監(jiān)聽緩存):
export function render(...) {
return (_openBlock(),_createBlock('div', null, [
_createVNode('div',{ onClick: _ctx.todo}, '做點有趣的事', 8 /* PROPS */,
['onClick']),
])
)
}
當我們開啟事件監(jiān)聽器緩存后:
export function render(...) {
return (_openBlock(),_createBlock('div', null, [
_createVNode('div',{
onClick: //開啟監(jiān)聽后
_cache[1] || (_cache[1] = (...args) =>_ctx.todo(...args)),
},'做點有趣的事'),
])
)
}
我們可以對比開啟事件監(jiān)聽緩存前后的代碼,轉換之后的代碼, 大家可能還看不懂, 但是不要緊,我們只需要觀察有沒有靜態(tài)標記即可,在Vue3的diff算法中, 只有有靜態(tài)標記的才會進行比較, 才會進行追蹤。
優(yōu)點4:ssr渲染
Vue2 中也是有 SSR 渲染的,但是 Vue3 中的 SSR 渲染相對于 Vue2 來說,性能方面也有對應的提升。
當存在大量靜態(tài)內容時,這些內容會被當作純字符串推進一個 buffer 里面,即使存在動態(tài)的綁定,會通過模版插值潛入進去。這樣會比通過虛擬 dmo 來渲染的快上很多。
當靜態(tài)內容大到一個量級的時候,會用_createStaticVNode 方法在客戶端去生成一個 static node,這些靜態(tài) node,會被直接 innerHtml,就不需要再創(chuàng)建對象,然后根據(jù)對象渲染。
優(yōu)點5:更好的Ts支持
vue2不適合使用ts,原因在于vue2的Option API風格。options是個簡單對象,而ts是一種類型系統(tǒng)、面向對象的語法。兩者有點不匹配。
在vue2結合ts的具體實踐中,要用 vue-class-component 強化 vue 組件,讓 Script 支持 TypeScript 裝飾器,用 vue-property-decorator 來增加更多結合 Vue 特性的裝飾器,最終搞的ts的組件寫法和js的組件寫法差別挺大。
在vue3中,量身打造了defineComponent函數(shù),使組件在ts下,更好的利用參數(shù)類型推斷 。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('')
}
優(yōu)點6:Compostion API: 組合API/注入API
傳統(tǒng)的網頁是html/css/javascript(結構/樣式/邏輯)分離。vue通過組件化的方式,將聯(lián)系緊密的結構/樣式/邏輯放在一起,有利于代碼的維護。compostionapi更進一步,著力于JS(邏輯)部分,將邏輯相關的代碼放在一起,這樣更有利于代碼的維護。
在vue2的組件內使用的是Option API風格(data/methods/mounted)來組織的代碼,這樣會讓邏輯分散,舉個例子就是我們完成一個計數(shù)器功能,要在data里聲明變量,在methods定義響應函數(shù),在mounted里初始化變量,如果在一個功能比較多、代碼量比較大的組件里,你要維護這樣一個功能,就需要在data/methods/mounted反復的切換到對應位置,然后進行代碼的更改。
而在vue3中,使用setup函數(shù)。如下所示跟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,
}
優(yōu)點7:更先進的組件
vue2是不允許這樣寫的,組件必須有一個跟節(jié)點,現(xiàn)在可以這樣寫,vue將為我們創(chuàng)建一個虛擬的Fragment節(jié)點。
<template> <div>華為云享專家</div> <div>全棧領域博主</div> </template>
在Suspended-component完全渲染之前,備用內容會被顯示出來。如果是異步組件,Suspense可以等待組件被下載,或者在設置函數(shù)中執(zhí)行一些異步操作。
優(yōu)點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官方實現(xiàn)的 createApp 會給我們的 template 映射生成 html 代碼,但是要是你不想渲染生成到 html ,而是要渲染生成到 canvas 之類的不是html的代碼的時候,那就需要用到 Custom Renderer API 來定義自己的 render 渲染生成函數(shù)了。
import { createApp } from "./runtime-render";
import App from "./src/App"; // 根組件
createApp(App).mount('#app');
使用自定義渲染API,如weex和myvue這類方案的問題就得到了完美解決。只需重寫createApp即可。
優(yōu)點9:按需編譯,體積比vue2.x更小
框架的大小也會影響其性能。這是 Web 應用程序的唯一關注點,因為需要即時下載資源,在瀏覽器解析必要的JavaScript 之前該應用程序是不可交互的。對于單頁應用程序尤其如此。盡管 Vue 一直是相對輕量級的(Vue 2 的運行時大小壓縮為 23 KB)。
在 Vue 3 中,通過將大多數(shù)全局 API 和內部幫助程序移至 ES 模塊導出來,實現(xiàn)了這一目標。這使現(xiàn)代的打包工具可以靜態(tài)分析模塊依賴性并刪除未使用的導出相關的代碼。模板編譯器還會生成友好的 Tree-shaking 代碼,在模板中實際使用了該功能時才導入該功能的幫助程序。
框架的某些部分永遠不會 Tree-shaking,因為它們對于任何類型的應用都是必不可少的。我們將這些必不可少的部分的度量標準稱為基準尺寸。盡管增加了許多新功能,但 Vue 3 的基準大小壓縮后約為 10 KB,還不到 Vue 2 的一半。
優(yōu)點10:支持多根節(jié)點組件
Vue3 一個模板不再限制有多個根節(jié)點,(多個根節(jié)點上的 Attribute 繼承) 需要顯式定義 attribute 應該分布在哪里。否則控制臺會給出警告提示。
在 Vue 3 中,組件現(xiàn)在正式支持多根節(jié)點組件,即片段!
在 2.x 中,不支持多根組件,當用戶意外創(chuàng)建多根組件時會發(fā)出警告,因此,為了修復此錯誤,許多組件被包裝在一個中。如下
<template>
<div>
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
</template>
在 3.x 中,組件現(xiàn)在可以有多個根節(jié)點!但是,這確實要求開發(fā)者明確定義屬性應該分布在哪里。
<template> <header>...</header> <main v-bind="$attrs">...</main> <footer>...</footer> </template>
總結:
- Vue是國內最火的前端框架之一。性能提升,運行速度是vue2的1.2-2倍。
- 體積更小,按需編譯體積vue2要更小。
- 類型推斷,更好的支持ts這個也是趨勢。
- 高級給予,暴露了更底層的API和提供更先進的內置組件。
- 組合API,能夠更好的組織邏輯,封裝邏輯,復用邏輯
到此這篇關于vue3 對比 vue2 有什么優(yōu)點的文章就介紹到這了,更多相關vue3 對比 vue2 的優(yōu)點內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue3使用h函數(shù)封裝組件和$attrs和props的區(qū)別詳解
這篇文章主要為大家詳細介紹了vue3使用h函數(shù)封裝組件和$attrs和props的區(qū)別,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2025-10-10
el-table表格動態(tài)合并相同數(shù)據(jù)單元格(可指定列+自定義合并)
工作時遇到的el-table合并單元格的需求,本文主要介紹了el-table表格動態(tài)合并相同數(shù)據(jù)單元格(可指定列+自定義合并),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07
vue中的this.$refs,this.$emit,this.$store,this.$nextTick的使用方式
這篇文章主要介紹了vue中的this.$refs,this.$emit,this.$store,this.$nextTick的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
vue項目實現(xiàn)設置根據(jù)路由高亮對應的菜單項操作
這篇文章主要介紹了vue項目實現(xiàn)設置根據(jù)路由高亮對應的菜單項操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08

