1. 架構設計差異
Vue2 的 Options API
Vue2 採用 Options API 組織代碼,通過不同的選項(data、methods、computed 等)來定義組件:
// Vue2 Options API
export default {
data() {
return {
count: 0,
message: 'Hello Vue2'
}
},
methods: {
increment() {
this.count++
}
},
computed: {
doubledCount() {
return this.count * 2
}
},
mounted() {
console.log('Component mounted')
}
}
Vue3 的 Composition API
Vue3 引入了 Composition API,提供更靈活的代碼組織方式:
// Vue3 Composition API
import { ref, computed, onMounted } from 'vue'
export default {
setup() {
const count = ref(0)
const message = ref('Hello Vue3')
const increment = () => {
count.value++
}
const doubledCount = computed(() => count.value * 2)
onMounted(() => {
console.log('Component mounted')
})
return {
count,
message,
increment,
doubledCount
}
}
}
優勢對比:
- 更好的邏輯複用:Composition API 使得提取和重用邏輯變得更加容易
- 更靈活的代碼組織:相關功能可以組織在一起,而不是分散在不同的選項中
- 更好的 TypeScript 支持:類型推斷更加準確和自然
2. 響應式系統重寫
Vue2 的響應式原理
Vue2 使用 Object.defineProperty 實現響應式:
// Vue2 響應式原理簡化版
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`讀取 ${key}: ${val}`)
return val
},
set(newVal) {
console.log(`設置 ${key}: ${newVal}`)
val = newVal
// 觸發更新
}
})
}
侷限性:
- 無法檢測對象屬性的添加或刪除
- 對數組的索引修改和長度修改無法追蹤
- 需要額外的
$set和$delete方法
Vue3 的 Proxy 實現
Vue3 使用 ES6 的 Proxy 重構響應式系統:
// Vue3 響應式原理簡化版
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
console.log(`讀取 ${String(key)}`)
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
console.log(`設置 ${String(key)}: ${value}`)
const result = Reflect.set(target, key, value, receiver)
// 觸發更新
return result
}
})
}
優勢:
- 支持對象和數組的全方位監聽
- 性能更好,特別是對於大型對象
- 無需特殊 API 處理新增/刪除屬性
3. 性能優化
編譯時優化
Vue3 在編譯階段進行了多項優化:
-
靜態樹提升(Static Tree Hoisting)
// Vue3 會將靜態內容提升到渲染函數外 const _hoisted_1 = /*#__PURE__*/_createVNode("div", null, "靜態內容") -
補丁標誌(Patch Flags)
// Vue3 在編譯時標記動態內容,減少運行時比較 _createVNode("div", { id: _ctx.id, class: _ctx.className }, null, 8 /* PROPS */, ["id", "class"]) -
樹結構拍平(Tree Flattening)
- 只追蹤動態子節點,減少虛擬 DOM 遍歷深度
體積優化
- Vue3 通過 Tree-shaking 支持,未使用的功能不會打包到最終產物中
- 相比 Vue2,運行時體積減少約 41%
4. TypeScript 支持
Vue2 的 TypeScript 支持
Vue2 對 TypeScript 的支持需要通過裝飾器實現:
// Vue2 + TypeScript
import { Component, Vue } from 'vue-property-decorator'
@Component
export default class MyComponent extends Vue {
private count: number = 0
private increment(): void {
this.count++
}
}
Vue3 的原生 TypeScript 支持
Vue3 使用 TypeScript 重寫,提供更好的類型推斷:
// Vue3 + TypeScript
import { defineComponent, ref } from 'vue'
interface User {
name: string
age: number
}
export default defineComponent({
setup() {
const count = ref<number>(0)
const user = ref<User>({
name: 'John',
age: 25
})
const increment = (): void => {
count.value++
}
return {
count,
user,
increment
}
}
})
5. 新的組件和 API
Fragment 片段
Vue3 支持多根節點組件:
<!-- Vue3 Fragment -->
<template>
<header>頭部</header>
<main>主要內容</main>
<footer>底部</footer>
</template>
Teleport 傳送
將組件渲染到 DOM 中的其他位置:
<template>
<div class="modal-container">
<Teleport to="body">
<div class="modal">
模態框內容
</div>
</Teleport>
</div>
</template>
Suspense 異步組件
更好的異步組件加載體驗:
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>加載中...</div>
</template>
</Suspense>
</template>
6. 生命週期變化
Vue2 生命週期
export default {
beforeCreate() {},
created() {},
beforeMount() {},
mounted() {},
beforeUpdate() {},
updated() {},
beforeDestroy() {},
destroyed() {}
}
Vue3 生命週期
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('組件掛載')
})
onUpdated(() => {
console.log('組件更新')
})
onUnmounted(() => {
console.log('組件卸載')
})
}
}
主要變化:
beforeDestroy→onBeforeUnmountdestroyed→onUnmounted
7. 遷移指南
漸進式遷移策略
- 使用兼容版本:Vue2.7 提供了部分 Vue3 特性的向後兼容
- 混合使用:在 Vue2 項目中逐步引入 Composition API
- 使用遷移構建版本:Vue3 提供了兼容 Vue2 的構建版本
常見 API 變化
// Vue2
this.$set(this.obj, 'key', value)
this.$delete(this.obj, 'key')
// Vue3
import { set, del } from 'vue'
set(obj, 'key', value)
del(obj, 'key')
// 事件總線
// Vue2
Vue.prototype.$bus = new Vue()
// Vue3
import mitt from 'mitt'
app.config.globalProperties.$bus = mitt()
8. 實際應用示例
邏輯複用對比
Vue2 Mixins:
// counterMixin.js
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
// 使用
import counterMixin from './counterMixin'
export default {
mixins: [counterMixin]
}
Vue3 Composables:
// useCounter.js
import { ref } from 'vue'
export function useCounter() {
const count = ref(0)
const increment = () => {
count.value++
}
return {
count,
increment
}
}
// 使用
import { useCounter } from './useCounter'
export default {
setup() {
const { count, increment } = useCounter()
return { count, increment }
}
}
總結
Vue3 在保留 Vue2 核心概念的同時,通過架構重構帶來了顯著的性能提升和更好的開發體驗。主要優勢包括:
- 更好的性能:更小的包體積、更快的渲染速度
- 更好的 TypeScript 支持:完整的類型推斷和類型安全
- 更好的邏輯複用:Composition API 提供更靈活的邏輯組織方式
- 更好的可維護性:相關功能集中管理,代碼更清晰
對於新項目,強烈推薦直接使用 Vue3。對於現有 Vue2 項目,可以根據實際情況制定漸進式遷移計劃。