Vue3(正式名稱為 Vue.js 3)是 Vue.js 前端框架的第三個主要版本,于 2020 年 9 月正式發布。作為對 Vue2 的重大升級,Vue3 在核心架構、性能優化、開發體驗等方面進行了全面重構,同時保持了 Vue 一貫的“漸進式框架”理念,讓開發者可以根據需求逐步采用其新特性。
一、Vue3 的核心改進
1. 全新的響應式系統
Vue3 放棄了 Vue2 中基于?Object.defineProperty
?的響應式實現,轉而采用?Proxy
?API,帶來以下優勢:
原生支持數組索引和長度的響應式變化,無需像 Vue2 那樣重寫數組方法(如?push
、splice
);
支持對象動態添加/刪除屬性的響應式監聽,Vue2 中需通過?Vue.set
/this.$set
?手動處理;
響應式系統更高效,僅在訪問屬性時建立依賴,而非遞歸遍歷對象所有屬性;
支持?Map
、Set
?等原生集合類型的響應式。
示例:Vue3 中動態添加響應式屬性
import { reactive } from 'vue' const state = reactive({ name: 'Vue3' }) // 動態添加屬性,自動具備響應式 state.age = 5 console.log(state.age) // 5(視圖會同步更新)
2. 組合式 API(Composition API)
組合式 API 是 Vue3 的核心特性之一,旨在解決 Vue2 選項式 API(Options API)在大型項目中的痛點:
選項式 API 中,邏輯分散在?data
、methods
、computed
?等選項中,復雜組件的邏輯難以聚合和用;
組合式 API 允許將相關邏輯(如數據、方法、監聽)封裝在一個函數中,實現“按功能組織代碼”,而非“按選項類型組織代碼”;
支持在多個組件間復用復雜邏輯,無需依賴混入(Mixin),避免混入帶來的命名沖突和邏輯來源不清晰問題。
示例:組合式 API 實現計數器邏輯
import { ref, computed, onMounted } from 'vue' export default {setup() {// 1. 定義響應式數據const count = ref(0)// 2. 定義計算屬性const doubleCount = computed(() => count.value * 2)// 3. 定義方法const increment = () => {count.value++}// 4. 生命周期鉤子onMounted(() => {console.log('組件掛載完成,初始 count 為', count.value)})// 5. 暴露給模板使用return { count, doubleCount, increment }} }
3. 更好的 TypeScript 支持
Vue3 從底層使用 TypeScript 重寫,相比 Vue2(需通過聲明文件兼容 TypeScript),提供了更完善的類型推導:
組合式 API 中的?ref
、reactive
?等 API 可自動推導數據類型,減少手動定義類型的工作量;
組件的?props
、emits
?選項支持精確的類型校驗;
支持在模板中進行類型檢查(需配合 Volar 編輯器插件),提前發現類型錯誤。
示例:TypeScript + 組合式 API 定義 props
import { defineProps } from 'vue' // 定義 props 并指定類型 const props = defineProps<{title: stringcount?: number // 可選屬性isVisible: boolean }>() // 使用 props 時自動獲得類型提示 console.log(props.title.length) // 無類型錯誤 console.log(props.count?.toFixed(2)) // 可選鏈語法安全使用
4. 性能優化
Vue3 在編譯和運行時層面進行了多項優化,性能顯著優于 Vue2:
編譯優化:模板編譯時生成更高效的渲染函數,減少虛擬 DOM 的對比次數(如靜態節點提升、補丁標記優化);靜態屬性(如?class="btn"
)會被提取到渲染函數外部,避免每次渲染時重復創建;條件渲染(v-if
)和列表渲染(v-for
)的編譯邏輯優化,減少不必要的 DOM 操作。
運行時優化:響應式系統基于?Proxy
,減少不必要的依賴追蹤;虛擬 DOM 算法優化,對比時僅關注動態節點,提升更新效率;支持片段(Fragments),組件可返回多個根節點,無需額外包裹?div
,減少 DOM 層級。
5. 內置組件與 API 調整
Vue3 對部分內置組件和 API 進行了調整,增強功能或簡化使用:
特性 | Vue2 情況 | Vue3 改進 |
---|---|---|
片段(Fragments) | 組件必須有唯一根節點,需用?div ?包裹 | 支持多根節點,無需包裹,編譯時自動處理 |
v-model | 語法復雜,需配合?sync ?修飾符實現雙向綁定 | 簡化語法,支持多個?v-model ,可自定義綁定屬性和事件 |
Teleport | 無內置組件,需通過第三方庫實現“組件內容掛載到指定 DOM 位置” | 內置?<Teleport> ?組件,輕松實現彈窗、下拉菜單等場景 |
Suspense | 無內置支持,異步組件加載狀態需手動處理 | 內置?<Suspense> ?組件,統一管理異步組件的加載、錯誤狀態 |
生命周期鉤子 | 選項式 API(如?mounted 、updated ) | 組合式 API 中提供獨立函數(如?onMounted 、onUpdated ),更靈活 |
二、Vue3 的兩種組件寫法
Vue3 支持兩種組件開發方式,開發者可根據項目需求和團隊習慣選擇:
1. 選項式 API(Options API)
與 Vue2 的寫法兼容,適合簡單組件或習慣選項式開發的開發者。Vue3 對選項式 API 進行了部分兼容優化,確保現有 Vue2 項目可平滑遷移。
2. 單文件組件(SFC)+ 組合式 API
Vue3 推薦的寫法,結合單文件組件(.vue 文件)和組合式 API,適合復雜組件和大型項目。Vue3 還支持?<script setup>
?語法糖,進一步簡化組合式 API 的代碼:
無需手動導出組件(export default
);
無需在?setup()
?函數中返回數據和方法,直接定義即可在模板中使用;
支持自動導入?ref
、computed
?等 API(需配合構建工具配置)。
三、Vue3 的生態系統
Vue3 發布后,其官方生態工具也已同步升級,確保開發體驗的一致性:
1. 構建工具:Vite
Vite 是 Vue 作者尤雨溪開發的新一代構建工具,相比 Webpack,具有以下優勢:
開發環境啟動速度極快(基于 ES 模塊原生支持,無需打包);
熱更新(HMR)響應迅速,修改代碼后立即生效;
默認支持 Vue3、TypeScript、JSX 等,零配置即可使用;
生產環境基于 Rollup 打包,體積小、性能優。
創建 Vue3 + Vite 項目的命令:
# 使用 npm npm create vite@latest my-vue3-project -- --template vue # 進入項目目錄并安裝依賴 cd my-vue3-project npm install # 啟動開發服務器 npm run dev
2. 路由:Vue Router 4
Vue Router 4 是 Vue3 的官方路由插件,與 Vue3 深度兼容,主要改進:
支持組合式 API,提供?useRouter
、useRoute
?等 Hook,方便在 setup 函數中使用路由;
支持路由參數的響應式監聽,無需手動監聽?$route
?變化;
優化路由匹配算法,支持動態路由和嵌套路由的更靈活配置。
示例:Vue Router 4 在組合式 API 中的使用
import { useRouter, useRoute } from 'vue-router' export default {setup() {const router = useRouter()const route = useRoute()// 獲取路由參數console.log(route.params.id)// 跳轉路由const goToHome = () => {router.push('/home')}return { goToHome }} }
3. 狀態管理:Pinia
Pinia 是 Vue3 官方推薦的狀態管理庫,替代了 Vue2 中的 Vuex,主要優勢:
完全支持 TypeScript,類型推導更完善;
簡化 API,無需?mutations
(Pinia 中直接通過?actions
?修改狀態,支持同步和異步);
支持組合式 API,可在 setup 函數中輕松使用;
體積更小,性能更優,支持多倉庫(多個 Store)。
示例:創建 Pinia Store 并使用
// 1. 創建 Store(src/stores/counter.js) import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', {state: () => ({ count: 0 }),actions: {increment() {this.count++},async incrementAsync() {await new Promise(resolve => setTimeout(resolve, 1000))this.count++}},getters: {doubleCount: (state) => state.count * 2} })// 2. 在組件中使用 import { useCounterStore } from '@/stores/counter' import { setup } from 'vue' export default {setup() {const counterStore = useCounterStore()return {count: counterStore.count,doubleCount: counterStore.doubleCount,increment: counterStore.increment,incrementAsync: counterStore.incrementAsync}