The main differences between Vue 2 and Vue 3
Vue 2 and Vue 3 exhibit significant differences in architecture, API design, performance optimization, and more. Vue 3 introduces new features such as the Composition API and a revamped reactivity system, while also optimizing the virtual DOM and bundle size. Below is a detailed comparison focusing on core differences.
Reactivity System Overhaul
Vue 2 uses Object.defineProperty
for reactivity, which has limitations like inability to detect new properties in arrays/objects:
// Vue 2 reactivity example
data() {
return {
obj: { a: 1 },
arr: [1,2,3]
}
},
mounted() {
this.obj.b = 2 // Not reactive
this.arr[3] = 4 // Not reactive
}
Vue 3 adopts Proxy for reactivity, supporting dynamic property addition and array index modification:
// Vue 3 reactivity example
setup() {
const state = reactive({
obj: { a: 1 },
arr: [1,2,3]
})
state.obj.b = 2 // Reactive
state.arr[3] = 4 // Reactive
return { state }
}
Composition API vs. Options API
Vue 2 organizes code using the Options API:
// Vue 2 Options API
export default {
data() { return { count: 0 } },
methods: {
increment() { this.count++ }
},
computed: {
double() { return this.count * 2 }
}
}
Vue 3 introduces the Composition API for better logic reuse:
// Vue 3 Composition API
import { ref, computed } from 'vue'
export default {
setup() {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, double, increment }
}
}
Lifecycle Changes
Vue 3 adjusts lifecycle hooks:
beforeCreate
-> Usesetup()
created
-> Usesetup()
beforeMount
->onBeforeMount
mounted
->onMounted
beforeUpdate
->onBeforeUpdate
updated
->onUpdated
beforeDestroy
->onBeforeUnmount
destroyed
->onUnmounted
// Vue 3 lifecycle example
import { onMounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('Component mounted')
})
}
}
Template Syntax Differences
Multiple Root Nodes Support
Vue 2 requires a single root node:
<!-- Vue 2 template -->
<template>
<div>
<header></header>
<main></main>
</div>
</template>
Vue 3 supports multiple root nodes:
<!-- Vue 3 template -->
<template>
<header></header>
<main></main>
</template>
v-model Changes
Vue 2's .sync
modifier is replaced by multiple v-model
in Vue 3:
<!-- Vue 2 -->
<ChildComponent :title.sync="pageTitle" />
<!-- Vue 3 -->
<ChildComponent v-model:title="pageTitle" />
Performance Optimizations
Virtual DOM Rewrite
Vue 3's virtual DOM generation is faster:
- Compile-time static node marking
- Event caching optimization
- Block Tree optimization
Reduced Bundle Size
Vue 3 leverages Tree-shaking, reducing core library size from ~20KB in Vue 2 to ~10KB.
TypeScript Support
Vue 3 is rewritten in TypeScript, offering better type inference:
// Vue 3 + TS example
import { defineComponent } from 'vue'
interface State {
count: number
}
export default defineComponent({
setup(): { count: number; increment: () => void } {
const count = ref<number>(0)
const increment = () => {
count.value++
}
return { count, increment }
}
})
Global API Changes
Vue 2 global APIs are attached to the Vue constructor:
// Vue 2 global APIs
import Vue from 'vue'
Vue.component('MyComp', { /* ... */ })
Vue.directive('focus', { /* ... */ })
Vue 3 adopts modular imports:
// Vue 3 global APIs
import { createApp } from 'vue'
const app = createApp({})
app.component('MyComp', { /* ... */ })
app.directive('focus', { /* ... */ })
Custom Renderer
Vue 3 provides a custom renderer API for non-DOM environments:
import { createRenderer } from 'vue'
const { render, createApp } = createRenderer({
patchProp,
insert,
remove,
createElement
// ...Other platform-specific APIs
})
Fragments and Teleport
Vue 3 introduces the <Teleport>
component for content teleportation:
<template>
<button @click="showModal">Open Modal</button>
<Teleport to="body">
<Modal v-if="isOpen"/>
</Teleport>
</template>
Async Component Improvements
Vue 3 uses defineAsyncComponent
for async components:
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
Transition Class Name Changes
Vue 3 transition class names align better with CSS conventions:
v-enter
->v-enter-from
v-leave
->v-leave-from
/* Vue 3 transition example */
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn