Vue3.0七大亮點

2021-12-23 前端開發
一、性能比2.x快1.2~2倍diff算法的優化

在vue2中,虛擬dom是全量比較的。

在vue3中,增加了靜態標記PatchFlag。在創建vnode的時候,會根據vnode的內容是否可以變化,為其添加靜態標記PatchFlag。diff的時候,只會比較有PatchFlag的節點。PatchFlag是有類型的,比如一個可變化文本節點,會將其添加PatchFlag枚舉值為TEXT的靜態標記。這樣在diff的時候,只需比對文本內容。需要比對的內容更少了。PatchFlag還有動態class、動態style、動態屬性、動態key屬性等枚舉值。

render階段的靜態提升(render階段指生成虛擬dom樹的階段)

在vue2中,一旦檢查到數據變化,就會re-render組件,所有的vnode都會重新創建一遍,形成新的vdom樹。

在vue3中,對於不參與更新的vnode,會做靜態提升,只會被創建一次,在re-render時直接復用。

靜態提升可以理解為第一次render不參與更新的vnode節點的時候,保存它們的引用。re-render新vdom樹時,直接拿它們的引用過來即可,無需重新創建。

事件偵聽緩存

在vue2中,我們寫的@click="onClick"也是被當作動態屬性,diff的時候也要對比。但我們知道它不會變化,比如變成@click="onClick2",綁定別的值。

在vue3中,如果事件是不會變化的,會將onClick緩存起來(跟靜態提升達到的效果類似),該節點也不會被標記上PatchFlag(也就是無需更新的節點)。這樣在render和diff兩個階段,事件偵聽屬性都節約了不必要的性能消耗。

我曾經維護過一個擁有很龐大dom樹的頁面。由於節點非常多,無需參與更新的節點也很多,使用vue2的情況下,在render和diff兩個階段,消費了很多性能,如果當時有vue3的話,我想性能會被優化很多。

減少創建組件實例的開銷

vue2.x每創建一個實例,在this上要暴露data、props、computed這些,都是靠Object.defineProperty去定義的。這部分操作還是挺費時的。

vue3.0中基於Proxy,減少了創建組件實例的性能開銷。

二、按需編譯,體積比Vue2.x更小(Tree shaking)

在vue3中,可以如下面這樣引用vue的功能函數,如果你的項目沒有用到watch,那編譯時就會把tree shaking掉。

import { computed, watch, nextTick } from "vue";
複製代碼

利用的就是 ES6 模塊系統import/export。

三、Compostion API: 組合API/注入API

這裡要說到代碼的組織方式,傳統的網頁是html/css/javascript(結構/樣式/邏輯)分離。vue/react通過組件化的方式,將聯繫緊密的結構/樣式/邏輯放在一起,有利於代碼的維護。

compostion api更進一步,著力於JavaScript(邏輯)部分,將邏輯相關的代碼放在一起,近而有利於代碼的維護。

在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,
  }
}
複製代碼

在我看來這就是Compostion API最大的特點,以功能為單位的代碼組織方式。同時它可以讓代碼更易重用。

說到重用,Compostion API的方式也比mixin的方式好很多,你可以清楚的看到組件使用的數據和方法來自哪個模塊,而mixin進組件的功能,常常會讓我們困惑此功能來自哪個mixin。

四、更好的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('') // => Property 'split' does not exist on type 'number'
 }
複製代碼

五、自定義渲染API(Custom Renderer API)vue2.x架構問題

vue2.x最開始支持運行在瀏覽器中,渲染到瀏覽器的dom上,隨著vue的流行,出現了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官方實現的 createApp 會給我們的 template 映射生成 html 代碼,但是要是你不想渲染生成到 html ,而是要渲染生成到 canvas 之類的不是html的代碼的時候,那就需要用到 Custom Renderer API 來定義自己的 render 渲染生成函數了。

// 你自己實現一個createApp,比如是渲染到canvas的。
import { createApp } from "./runtime-render";
import App from "./src/App"; // 根組件

createApp(App).mount('#app');
複製代碼

有了Custom Renderer API,如weex和myvue這類方案的問題就得到了完美解決。只需重寫createApp即可。

六,更先進的組件Fragment組件

// vue2是不允許這樣寫的,組件必須有一個跟節點,現在可以這樣寫,vue將為我們創建一個虛擬的Fragment節點。

<template>
  <div>Hello</div>
  <div>World</div>
</template>
複製代碼

這樣寫有何好處呢?一是如果根節點不是必要的,無需創建了,減少了節點數。二是Fragment節點是虛擬的,不會DOM樹中呈現。

Suspense組件
<Suspense>
  <template >
    <Suspended-component />
  </template>
  <template #fallback>
    Loading...
  </template>
</Suspense>
複製代碼

在Suspended-component完全渲染之前,備用內容會被顯示出來。如果是異步組件,Suspense可以等待組件被下載,或者在設置函數中執行一些異步操作。

七、更快的開發體驗(vite開發構建工具)

在使用webpack作為開發構建工具時,npm run dev都要等一會,項目越大等的時間越長。熱重載頁有幾秒的延遲,但是如果用vite來做vue3的開發構建工具,npm run dev 秒開,熱重載也很快。這種開發體驗真是很爽,拒絕等待。

vite的原理還是用了瀏覽器支持import關鍵字了,啟動項目不用webpack構建工具先構建了,瀏覽器直接請求路由對應的代碼文件,代理伺服器針對單個文件進行編譯並返回。如果請求的文件裡還import了其他文件,同理瀏覽器繼續發請求,代理伺服器返回。就這樣實現了npm run dev時無需編譯,實時請求實時編譯。

總結:

其他的,數據監聽方式變成了Proxy,消除了Object.defineProperty現有的限制(例如無法檢測新的屬性添加),並提供更好的性能。

vue3解決了vue2的一些問題,大型應用的性能問題、ts支持不友好問題,自定義渲染API解決體系架構存在的問題,如果在vue3的基礎上實現weex框架會好很多。也做出了很多優化,Compostion API讓代碼的組織形式更好。vite開發構建工具讓開發體驗更好,Tree shaking讓包更小、性能更優。

總的來說vue3還是非常棒的,帶來了很多非常好的新特性。

相關焦點

  • Vue3.0新特性
    reactivecomputed 和watch新的生命周期函數自定義函數--hooks函數Teleport - 瞬移組件的位置Suspense - 異步加載組件的新福音全局API的修改和優化更多的誓言性特性更好的Typescript 支持vue3.0
  • Vue3.0——生命周期講解
    而在Vue3.0中,Vue2.x Options API形式的生命周期鉤子函數和新的Composition API都可以使用,來看個示例代碼就明白了:整體代碼如下:const { createComponent, createApp, reactive } = Vueconst Counter = { props
  • Element-UI 死而復生,基於Vue3.0的版本來了
    element ui 2 github另外我們看到README.md下面的介紹:Element will stay with Vue 2.xFor Vue 3.0, we recommend using Element Plus from the same team意思是說Element UI 2將繼續保持基於Vue 2.x進行更新,另外基於Vue 3.0的版本將由原來的維護開發,項目取名為Element Plus。
  • Vue.js 3.0 "One Piece" 正式版發布
    Vue.js 3.0 正式版發布的內容為英文版本,原文見:https://github.com/vuejs/vue-next/releases。今天,我們非常自豪地宣布 Vue.js 3.0 "One Piece" 發布。
  • Vue 3.0前的 TypeScript 最佳入門實踐
    -- Add "scoped" attribute to limit CSS to this component only --><stylescoped></style>至此,準備開啟新的篇章 TypeScript極速入門 和 vue-property-decorator3、TypeScript極速入門3.1
  • Vue CLI 3.0 正式發布,Vue.js 開發標準化工具
    Vue CLI 3.0 已發布,該版本經歷了重構,旨在:減少現代前端工具的配置煩擾,尤其是在將多個工具混合在一起使用時;儘可能在工具鏈中加入最佳實踐,讓它成為任意
  • vue-element-admin 4.0.0 正式版發布
    重大改變 基於 vue-cli@3進行構建 調整了項目的目錄結構 mock 文件移至根目錄下 layout 從 views 文件夾下移至 src 下 使用了最新的 eslint-plugin-vue
  • 官方Element Plus for Vue 3.0 Beta 版本今天發布了!
    今天,Element Plus for Vue 3.0 Beta版本正式發布了!對,就是那個被外界傳言不再維護的Element UI!官方團隊幾乎重寫了每一行 代碼,用最Vue 3的方式呈現了最完美的Element,主要有:使用TypeScript開發,提供完整的類型定義文件使用Vue 3.0 Composition API
  • 從零開始擼一個Vue3.0組件庫-並上傳到NPM上
    前言今日前端早讀課文章由@傲夫靠斯投稿分享。
  • Vue.js系列之vue-router(上)(3)
    說明:我們項目現在用的是:vue2.0 + vue-cli + webpack + vue-router2.0 + vue-resource1.0.3
  • 【組件庫從0到1】Vite + Vue3 + TSX開發指南
    不少前端小夥伴問過我,說業務代碼寫了2、3年了,應該如何再進一步?村長的回答中大多數會提到兩個關鍵點:加強工程化實踐能力和底層原理源碼知識。工程化能力對於小夥伴們在工作中解決問題有直接影響,如果你想成為小組內的核心程式設計師,拿更高的職位和薪資,能夠給大家搭架子,解決問題,重難點突破是非常關鍵的幾個考察點。
  • Vue.js 框架作者公布 Vue 3 最新進展
    因此原本計劃 2020 年上半年發布 Vue 3,但考慮到目前的進度,不得不進行調整。現在的計劃是 7 月中旬發布 RC 版本,8 月初正式發布 3.0 版本。Vue Router目前存在部分與 vue-router@3.x 相關的路由鉤子 (router hook)行為一致性問題,這也是 Vue Router 沒有被標記為 Beta 的原因。不過在非關鍵項目上可以使用新的路由。
  • Vue2.0父子組件間通信
    vue2.0Vue.js是一套構建用戶界面的漸進式框架。與其他重量級框架不同的是,Vue 從根本上採用最小成本、漸進增量的設計。Vue 的核心庫只專注於視圖層,並且很容易與其他第三方庫或現有項目集成。另一方面,當與單文件組件和 Vue 生態系統支持的庫結合使用時,Vue 也完全能夠為複雜的單頁應用程式提供有力驅動。
  • 阿里面試官問山月在Vue3.0中為啥要用Proxy
    檢測不到對象屬性的添加和刪除:當你在對象上新加了一個屬性newProperty,當前新加的這個屬性並沒有加入vue檢測數據更新的機制(因為是在初始化之後添加的)。vue.$set是能讓vue知道你添加了屬性, 它會給你做處理,$set內部也是通過調用Object.defineProperty()去處理的無法監控到數組下標的變化,導致直接通過數組的下標給數組設置值,不能實時響應。
  • 在VUE2.0中使用PostCSS
    其實在 vue-loader 中僅需要簡單的配置即可拯救我們。vue-loader 中 PostCSS 配置vue-loader 中使用了 PostCSS 來處理 css,如下圖所示:上圖為 vue-loader 9.x、webpack 1.x 中配置方法autoprefixer
  • Vue3+TypeScript完整項目上手教程
    一個完整的Vue3+Ts項目,支持.vue和.tsx寫法項目地址:https://github.com/vincentzyc/vue3-demo.gitTypeScript 是JS的一個超集,主要提供了類型系統和對ES6的支持,使用 TypeScript 可以增加代碼的可讀性和可維護性,在 react 和 vue 社區中也越來越多人開始使用
  • 實戰教學使用 Vue3 重構 Vue2 項目(萬字好文推薦)
    集成Vue周邊庫我們將Vue CLI初始化的項目文件替換到用vite初始化的項目中去,然後修改packge.json中的相關依賴,然後重新安裝依賴即可"^3.6.5",    "vue": "^3.0.0-0",    "vue-class-component": "^8.0.0-0",    "vue-router": "^4.0.0-0",    "vuex": "^4.0.0-0"  },  "devDependencies": {    "vite": "^1.0.0-rc.1",
  • vue3-巧用指令
    來源 | https://xuxin123.com/web/vue3
  • 了解vue3.0的異步更新原理
    今天我們簡單了解下vue3.0的異步更新原理,了解一下effect,watchEffect的特點以及最主要queueFlush函數的實現(函數名字本意就是:排隊刷新)effect特點import { effect, reactive } from '.
  • Vue3.0+typescript+Vite+Pinia+Element-plus搭建vue3目前最流行的項目框架!
    隨著vue3.0的越來越受歡迎,開始有許多公司和個人開始學習並使用vue3開發項目。我從接觸學習並使用vue2,到現在的vue3,工作中也一直在使用vue。vue3也發布很長時間了,目前vue3+vite+ts再結合一些優秀的UI框架,如Element plus,Ant design,Naive UI,移動端的Vant UI,成為了較為流行的前端技術之一。那麼今天就帶大家一起來搭建一個Vue3的項目吧!兼容性注意Vite 需要 Node.js 版本 >= 12.0.0。