Vue3.0版本強勢升級點特性詳解
一、Composition API: 組合API/注入API
Vue3.0
在架構上相比vue2.x
做了升級,性能上得到了很大的提升,Composition API
的出現(xiàn),讓組件抽離、邏輯代碼復用更加靈活。
這里要說到代碼的組織方式,傳統(tǒng)的網(wǎng)頁是html/css/javascript(結構/樣式/邏輯)分離。vue/react通過組件化的方式,將聯(lián)系緊密的結構/樣式/邏輯放在一起,有利于代碼的維護。
Composition api
更進一步,著力于JavaScript(邏輯)部分,將邏輯相關的代碼放在一起,近而有利于代碼的維護。
在vue2的組件內(nèi),使用的是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, } }
在我看來這就是Composition API
最大的特點,以功能為單位的代碼組織方式。同時它可以讓代碼更易重用
。
說到重用,Composition API
的方式也比mixin
的方式好很多,你可以清楚的看到組件使用的數(shù)據(jù)和方法來自哪個模塊,而mixin進組件的功能,常常會讓我們困惑此功能來自哪個mixin
。
二、自定義渲染API(Custom Renderer API)
vue2.x架構問題
vue2.x最開始支持運行在瀏覽器中,渲染到瀏覽器的dom上,隨著vue的流行,出現(xiàn)了weex
和myvue
。
weex
:移動端跨平臺方案,需要渲染到移動設備。weex被寫在vue原項目里,缺點是這使vue原項目更大了,也不是通用解決方案。myvue
:小程序上使用,需要渲染到小程序框架上。myvue是單獨fork一份源代碼進行更改,缺點也非常明顯,myvue中vue的版本跟官方版本從fork的那一刻開始,就要開始不一致了。
vue2.x項目架構對于這種渲染到不同平臺不太友好,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ù)了。
// 你自己實現(xiàn)一個createApp,比如是渲染到canvas的。 import { createApp } from "./runtime-render"; import App from "./src/App"; // 根組件 createApp(App).mount('#app');
有了Custom Renderer API
,如weex
和myvue
這類方案的問題就得到了完美解決。只需重寫createApp
即可。
三、更先進的組件
Fragment組件
vue2
是不允許這樣寫的,組件必須有一個跟節(jié)點,現(xiàn)在可以這樣寫,vue將為我們創(chuàng)建一個虛擬的Fragment
節(jié)點。
<template> <div>Hello</div> <div>World</div> </template>
這樣寫有何好處呢?一是如果根節(jié)點不是必要的,無需創(chuàng)建了,減少了節(jié)點數(shù)。二是Fragment
節(jié)點是虛擬的,不會DOM樹
中呈現(xiàn)。
Suspense組件
<Suspense> <template > <Suspended-component /> </template> <template #fallback> Loading... </template> </Suspense>
在Suspended-component完全渲染之前,備用內(nèi)容會被顯示出來。如果是異步組件,Suspense
可以等待組件被下載,或者在設置函數(shù)中執(zhí)行一些異步操作。
四、更好的TS支持
vue2不適合使用ts
,原因在于vue2的Option API
風格。options
是個簡單對象,而ts是一種類型系統(tǒng)、面向?qū)ο蟮恼Z法。兩者有點不匹配。
在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('') // => Property 'split' does not exist on type 'number' });
五、更快的開發(fā)體驗(vite開發(fā)構建工具)
在使用webpack作為開發(fā)構建工具時,npm run dev都要等一會,項目越大等的時間越長。熱重載頁有幾秒的延遲,但是如果用vite來做vue3的開發(fā)構建工具,npm run dev 秒開,熱重載也很快。這種開發(fā)體驗真是很爽,拒絕等待。
vite
的原理還是用了瀏覽器支持import
關鍵字了,啟動項目不用webpack
構建工具先構建了,瀏覽器直接請求路由對應的代碼文件,代理服務器針對單個文件進行編譯并返回。如果請求的文件里還import了其他文件,同理瀏覽器繼續(xù)發(fā)請求,代理服務器返回。就這樣實現(xiàn)了npm run dev時無需編譯,實時請求實時編譯。
六、按需編譯,體積比Vue2.x更?。═ree shaking)
在vue3中,可以如下面這樣引用vue的功能函數(shù),如果你的項目沒有用到watch
,那編譯時就會把tree shaking
掉。
import { computed, watch, nextTick } from "vue";
利用的就是 ES6
模塊系統(tǒng)import
/export
。
七、性能比2.x快1.2~2倍
diff算法的優(yōu)化
在vue2中,虛擬dom是全量比較的。
在vue3中,增加了靜態(tài)標記PatchFlag。在創(chuàng)建vnode
的時候,會根據(jù)vnode的內(nèi)容是否可以變化,為其添加靜態(tài)標記PatchFlag。diff的時候,只會比較有PatchFlag的節(jié)點。 PatchFlag是有類型的,比如一個可變化文本節(jié)點,會將其添加PatchFlag枚舉值為TEXT的靜態(tài)標記。這樣在diff的時候,只需比對文本內(nèi)容。需要比對的內(nèi)容更少了。PatchFlag還有動態(tài)class、動態(tài)style、動態(tài)屬性、動態(tài)key屬性等枚舉值。
render階段的靜態(tài)提升(render階段指生成虛擬dom樹的階段)
在vue2中,一旦檢查到數(shù)據(jù)變化,就會re-render
組件,所有的vnode
都會重新創(chuàng)建一遍,形成新的vdom樹
。
在vue3中,對于不參與更新的vnode
,會做靜態(tài)提升,只會被創(chuàng)建一次,在re-render時直接復用。
靜態(tài)提升可以理解為第一次render不參與更新的vnode
節(jié)點的時候,保存它們的引用。re-render新vdom樹時,直接拿它們的引用過來即可,無需重新創(chuàng)建。
事件偵聽緩存
在vue2中,我們寫的@click="onClick"也是被當作動態(tài)屬性,diff的時候也要對比。但我們知道它不會變化,比如變成@click="onClick2",綁定別的值。
在vue3中,如果事件是不會變化的,會將onClick緩存起來(跟靜態(tài)提升達到的效果類似),該節(jié)點也不會被標記上PatchFlag
(也就是無需更新的節(jié)點)。這樣在render
和diff
兩個階段,事件偵聽屬性都節(jié)約了不必要的性能消耗。
我曾經(jīng)維護過一個擁有很龐大dom樹的頁面。由于節(jié)點非常多,無需參與更新的節(jié)點也很多,使用vue2的情況下,在render和diff兩個階段,消費了很多性能,如果當時有vue3的話,我想性能會被優(yōu)化很多。
減少創(chuàng)建組件實例的開銷
vue2.x每創(chuàng)建一個實例,在this上要暴露data、props、computed這些,都是靠Object.defineProperty去定義的。這部分操作還是挺費時的。
vue3.0中基于Proxy
,減少了創(chuàng)建組件實例的性能開銷。
總結:
- 其他的,數(shù)據(jù)監(jiān)聽方式變成了
Proxy
,消除了Object.defineProperty
現(xiàn)有的限制(例如無法檢測新的屬性添加),并提供更好的性能。 vue3
解決了vue2的一些問題,大型應用的性能問題、ts
支持不友好問題,自定義渲染API解決體系架構存在的問題,如果在vue3的基礎上實現(xiàn)weex框架會好很多。也做出了很多優(yōu)化,Composition API
讓代碼的組織形式更好。vite
開發(fā)構建工具讓開發(fā)體驗更好,Tree shaking
讓包更小、性能更優(yōu)。- 總的來說vue3還是非常棒,非常強大,帶來了很多非常好的新特性。
以上就是Vue3.0版本強勢升級點特性詳解的詳細內(nèi)容,更多關于Vue3.0版本升級特性的資料請關注腳本之家其它相關文章!
相關文章
vue使用showdown并實現(xiàn)代碼區(qū)域高亮的示例代碼
這篇文章主要介紹了vue使用showdown并實現(xiàn)代碼區(qū)域高亮的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10npm install卡在“sill idealTree buildDeps“問題的兩種解
本文主要介紹了npm install卡在“sill idealTree buildDeps“問題的兩種解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-03-03element-ui中頁面縮放時table表格內(nèi)容錯位的解決
這篇文章主要介紹了element-ui中頁面縮放時table表格內(nèi)容錯位的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08Vue超出文本框顯示省略號鼠標滑入顯示全部的實現(xiàn)方法
在Vue項目中經(jīng)常需要處理文本內(nèi)容過長的情況,這篇文章主要給大家介紹了關于Vue超出文本框顯示省略號鼠標滑入顯示全部的實現(xiàn)方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-10-10Vue中 v-if 和v-else-if頁面加載出現(xiàn)閃現(xiàn)的問題及解決方法
vue中v-if 和v-else-if在頁面加載的時候,不滿足條件的標簽會加載然后再消失掉,如果要解決這個問題,下面小編給大家?guī)砹藢嵗a,需要的朋友參考下吧2018-10-10Vue-router優(yōu)化import引入過多導致index文件臃腫問題
這篇文章主要為大家介紹了Vue-router優(yōu)化import引入過多導致index文件臃腫問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08