阿里云主机折上折
  • 微信号
Current Site:Index > The main differences between Vue 2 and Vue 3

The main differences between Vue 2 and Vue 3

Author:Chuan Chen 阅读数:42498人阅读 分类: Vue.js

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 -> Use setup()
  • created -> Use setup()
  • 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

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.