Vue3 Introduction

Vue3 is a progressive framework for building user interfaces.

ProgressiveIt means you can introduce only part of Vue's capabilities according to your project needs: from a simple page interaction enhancement, to building complete single-page applications (SPA), and even server-side rendering (SSR) applications, Vue3 is fully capable.

Vue3 is a progressive JavaScript front-end framework led by Evan You, officially released on September 18, 2020, with the codenameOne Piece。

Compared to Vue2, Vue3 completely rewrote the core architecture: the reactivity system went fromObject.definePropertyupgraded toProxy, introducing the Composition API, and comprehensively improving performance, TypeScript support, bundle size, and more.

Vue3's official positioning is:a framework that is easy to get started with, yet has enough power to support complex projects. It neither forces a specific architecture like Angular, nor requires heavy manual optimization like React; instead, it strikes a balance between ease of use and capability.

Essential Differences Between Vue3 and Vue2

Vue3 is not a patch upgrade of Vue2, but a complete rewrite.

Comparison ItemVue2Vue3
Reactivity PrincipleObject.defineProperty, cannot observe newly added properties and array index changesProxy, completely proxies all operations on the object, without the above limitations
Code OrganizationOptions API: data, methods, and computed are separatedComposition API: code is aggregated by logical concerns
TypeScript SupportAdapted later, limited type inferenceCore code rewritten in TypeScript, TS is a first-class citizen
Bundle SizeRuntime approximately 20KB (gzip)Supports Tree-shaking, on-demand bundling, minimum only 13.5KB
PerformanceBaselineInitial rendering is about 55% faster, update rendering is about 133% faster, memory usage is reduced by about 54%
Component Template Root NodeMust have exactly one root elementSupports multiple root nodes (Fragment)
Global APIMounted on the Vue constructor, multiple instances share stateThroughcreateAppcreating independent instances, with more thorough isolation

Core Features

Vue3's improvements span four dimensions: the reactivity system, API design, the compiler, and new built-in components.

Composition API

Composition API is the most important design change in Vue3; it solves the fundamental pain points of the Options API in Vue2:Related logic is scattered across different options, making reuse difficult。

In the Options API, the data for a "user search" feature may be scattered acrossdata、methods、computed、watchfour options; whereas Composition API allows you to write all the logic for the same feature together, and then extract it into reusable functions (Composables).

Example: Options API vs Composition API

<!-- Options API approach (supported by Vue2 / Vue3) -->
<script>
export default {
  data() {
    return {
count: 0, // counter data
username: 'example' // username data
    }
  },
  computed: {
doubled() { // double of count
      return this.count * 2
    }
  },
  methods: {
increment() { // increment the count
      this.count++
    }
  }
}
</script>

Example: Recommended Approach (script setup Syntax Sugar)

<!-- Composition API + script setup (Vue3 recommended approach) -->
<script setup>
import { ref, computed } from 'vue'

// Reactive data is declared directly, no need to return
const count = ref(0) // ref wraps primitive types
const username = ref('example')

// computed property
const doubled = computed(() => count.value * 2)

// Methods are defined directly as functions
function increment() {
count.value++ // Note: ref-wrapped values must be accessed through .value
}
</script>

<template>
  <!-- In templates, ref is automatically unwrapped, no need for .value -->
  <p>User: {{ username }}</p>
  <p>Count: {{ count }}, double: {{ doubled }}</p>
  <button @click="increment">+1</button>
</template>

<script setup>is syntax sugar for the Composition API: it lets you<script>directly write Composition API code at the top level, without manuallyreturn, all top-level variables and functions are automatically exposed to the template. This is currently the most recommended way to write single-file components in Vue3.

Reactivity System: Proxy Replaces defineProperty

Vue2's reactivity is based onObject.defineProperty, this approach has two issues that cannot be fundamentally solved: it cannot observe newly added object properties, and it cannot observe direct assignment to array elements by index. Vue3 usesProxyto fundamentally solve these two problems.

Example: ref and reactive

import { ref, reactive, watch } from 'vue'

// ref: suitable for primitive types (number, string, boolean)
// Accessing and modifying values requires .value
const count = ref(0)
count.value = 10

// reactive: suitable for objects and arrays
// Access properties directly, no need for .value
const user = reactive({
  name: 'EXAMPLE',
  age: 18,
  skills: ['vue', 'typescript']
})

// In Vue3, you can add new properties to an object and reactivity still works normally
user.email = 'example@example.com'  // In Vue2, this operation does not trigger view updates

// You can also modify array elements directly
user.skills[0] = 'vue3'  // In Vue2, this operation does not trigger view updates

// Watch reactive data changes
watch(count, (newVal, oldVal) => {
  console.log(`count from ${oldVal}to ${newVal}`)
})

Composable Functions (Composables)

Composables are the standard way to reuse stateful logic in Vue3, similar to React's custom Hooks.

It is conventional touseprefix the name, extract a complete piece of reactive logic into an independent function, and reuse it across multiple components.

Example: Custom Composable

// File path: composables/useCounter.js
// Encapsulate counter logic; any component can reuse it

import { ref, computed } from 'vue'

export function useCounter(initialValue = 0) {
  const count = ref(initialValue)           // Internal reactive state
  const doubled = computed(() => count.value * 2)  // Derived state

  function increment() { count.value++ }
  function decrement() { count.value-- }
  function reset() { count.value = initialValue }

  // Return the state and methods that need to be exposed externally
  return { count, doubled, increment, decrement, reset }
}

Example: Using Composable in Components

<script setup>
import { useCounter } from './composables/useCounter'

// Destructure and use directly; reactivity is preserved
const { count, doubled, increment, decrement, reset } = useCounter(10)
</script>

<template>
  <p>Current value: {{ count }}, doubled: {{ doubled }}</p>
  <button @click="increment">+1</button>
  <button @click="decrement">-1</button>
  <button @click="reset">Reset</button>
</template>

New Built-in Components

Vue3 introduces three new built-in components that solve three high-frequency scenarios in frontend development.

ComponentProblem SolvedTypical Use Cases
FragmentVue2 required component templates to have a single root node; Fragment allows multiple root nodes to coexist (no extra wrapping div needed)List item components, reducing unnecessary DOM nesting
TeleportRenders a component's HTML to any specified position in the DOM, breaking through the parent component's CSS stacking context limitationsGlobal Modal dialogs, Toast notifications, floating toolbars
SuspenseGracefully displays fallback content before async components finish loading, uniformly handling async waiting statesSkeleton screens for lazy-loaded components, loading indicators during route transitions

Example: Using Teleport to Implement a Global Modal

<script setup>
import { ref } from 'vue'
const showModal = ref(false)
</script>

<template>
  <button @click="showModal = true">Open Modal</button>

  <!--
Teleport mounts the modal content under body,
rather than inside the current component's parent element, avoiding z-index and overflow issues
 -->
  <Teleport to="body">
    <div v-if="showModal" class="modal-mask">
      <div class="modal-box">
        <p>This is a global modal</p>
        <button @click="showModal = false">Close</button>
      </div>
    </div>
  </Teleport>
</template>

Example: Using Suspense to Handle Async Component Loading

<!-- Parent component App.vue -->
<template>
  <Suspense>
    <!-- Default slot: async content -->
    <template #default>
      <AsyncUserProfile />  <!-- Async components that use await internally -->
    </template>
    <!-- fallback slot: content shown while loading -->
    <template #fallback>
      <div class="loading">Loading...</div>
    </template>
  </Suspense>
</template>

Tree-shaking Support

Vue3 changes all global APIs to named exports. With the tree-shaking capability of bundlers like Vite / webpack, unused APIs are not bundled into the final output.

Example: Importing APIs on Demand

// Vue2: All APIs are accessed through the global Vue object, which cannot be tree-shaken
// Vue.nextTick(...)
// Vue.set(obj, 'key', value)

// Vue3: Import on demand; only the functions actually used are included in the bundle
import { ref, computed, watch, nextTick, onMounted } from 'vue'

// Only these APIs are imported; unused ones (such as watchEffect, provide, etc.) will not be included in the bundle

Lifecycle Hooks

All lifecycle hooks corresponding to Vue3's Composition API are prefixed withonand are called withinsetupsetup().

Vue2 Options APIVue3 Composition APITrigger Timing
beforeCreate— (setup itself replaces this)Before instance initialization
created— (setup itself replaces this)Instance created
beforeMountonBeforeMountBefore mount
mountedonMountedMounted, DOM accessible
beforeUpdateonBeforeUpdateBefore data updates and DOM re-render
updatedonUpdatedAfter DOM re-render completes
beforeDestroyonBeforeUnmountBefore component unmount (name changed)
destroyedonUnmountedComponent unmount complete (name changed)

Example: Using Lifecycle Hooks

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const timer = ref(null)
const count = ref(0)

// Executed after the component is mounted (DOM can be safely manipulated)
onMounted(() => {
console.log('Component mounted')
// Start a timer that increments the count every second
  timer.value = setInterval(() => {
    count.value++
  }, 1000)
})

// Executed when the component unmounts (clean up side effects to avoid memory leaks)
onUnmounted(() => {
  clearInterval(timer.value)
console.log('Timer cleared')
})
</script>

<template>
  <p>Running for: {{ count }} seconds</p>
</template>

Full TypeScript Support

Vue3's core library is completely rewritten in TypeScript, providing precise type inference. Combined with<script setup lang="ts">, you can use TypeScript directly in single-file components without additional configuration.

Example: Using TypeScript in script setup

<script setup lang="ts">
import { ref, computed } from 'vue'

// Interface defining the data structure within the component
interface User {
  id: number
  name: string
  email?: string
}

// ref automatically infers the type from the initial value, or it can be explicitly specified
const user = ref<User>({
  id: 1,
  name: 'EXAMPLE',
})

// defineProps: declare and infer prop types
const props = defineProps<{
 title: string       //Required
 count?: number      //Optional
}>()

// defineEmits: declare and type-check custom events
const emit = defineEmits<{
 (e: 'update', value: number): void
 (e: 'close'): void
}>()

const displayName = computed(() => user.value.name.toUpperCase())

function handleUpdate() {
  emit('update', 42)
}
</script>

Application Areas

As a complete frontend framework ecosystem, Vue3 covers a wide range of scenarios, from single-page applications to server-side rendering, from Web to mobile.

Single-page Applications (SPA)

This is the most classic use case for Vue3. Combined withVue Router 4for frontend routing,Pinia(the state management library officially recommended by Vue3, replacing Vuex) to manage global state, you can build fully functional single-page applications.

Typical project types: enterprise admin systems, data dashboards, e-commerce storefronts.

Server-side Rendering (SSR) and Static Site Generation (SSG)

Nuxt 3is a full-stack framework based on Vue3, deeply integrating SSR and SSG capabilities. It automatically handles the complexity of server-side rendering, allowing developers to build SEO-friendly applications just like writing regular Vue components.

Suitable scenarios: content websites, blogs, documentation sites, marketing landing pages.

Mobile and Cross-platform

uni-appSupports using Vue3 syntax to simultaneously develop WeChat Mini Programs, Alipay Mini Programs, H5, and Apps (iOS/Android).Ionic + Vue3is suitable for building high-quality hybrid mobile applications.

Desktop Applications

Electron + Vue3(through toolchains like electron-vite) can package Vue3 applications as cross-platform desktop applications.Tauri + Vue3is a popular alternative in recent years, using Rust as the backend, resulting in smaller application size and better performance.

UI Component Library Ecosystem

The Vue3 ecosystem offers a rich selection of mature component libraries:

Component LibraryPositioningSuitable Scenarios
Element PlusPC desktop component library, the Vue3 version of Element UIEnterprise admin systems, data-intensive applications
Ant Design VueVue implementation of Ant Design, with mature design specificationsMid/back-office systems, enterprise applications
Vant 4Mobile component library, lightweight and high-performanceMobile H5, WeChat Mini Programs
Vuetify 3Material Design style component libraryConsumer-facing web applications
Naive UIWritten in TypeScript, with strong theme customization capabilitiesProjects requiring deep theme customization
shadcn-vueBased on Radix UI and Tailwind, a collection of copy-paste componentsProjects that value UI uniqueness

Development History

Vue.js grew from a personal project into one of the top three frontend frameworks in the world. Each major version was driven by clear engineering needs.

Origins (2013 - 2014)

Vue.js was created by Evan You during his time at Google. In 2013, he explored the Angular development experience, hoping to extract his favorite part — the data-driven view update mechanism — while removing the parts he considered overly heavy.

In February 2014, Vue.js 0.8.0 was publicly released. It subsequently gained attention from the Laravel community and gradually became well-known in the JavaScript community.

Vue 1.x Era (2015)

In October 2015, Vue 1.0 was officially released, codenamed Evangelion. That same year,Vue Router(2015.08)、Vuex(2015.11)、Vue CLI(December 2015) were released successively, marking Vue's evolution from a view-layer library into a complete progressive framework.

Vue 2.x Era (2016 - 2020)

In October 2016, Vue 2.0 was released, introducing a virtual DOM approach (inspired by React), supporting server-side rendering (SSR), and significantly improving performance.

The Vue 2 era was the fastest expansion phase of the Vue ecosystem: component libraries such as Element UI emerged, Nuxt.js appeared, and Vue became one of the frontend frameworks with the most GitHub stars in the world.

In February 2019, Vue 2.6 was released, codenamed Macross. This was the last major version of Vue 2, bridging the past and the future.

Vue 3.0 Release (2020)

Vue3 development began in late 2018 and took about two years, going through 30+ RFCs (Request for Comments), 2600+ commits, and 628 PRs from 99 contributors.

On September 18, 2020, Vue 3.0 was officially released, codenamed One Piece. Core changes:

  • The reactive system is based onProxyRewritten
  • Introduced Composition API
  • Full TypeScript support
  • Added Fragment, Teleport, Suspense
  • Supports Tree-shaking, significantly reduced bundle size

Ecosystem Maturation Stage (2021 - 2022)

TimeVersion / EventMilestone significance
2021-08Vue 3.2<script setup>The syntactic sugar officially stabilized,<style> v-bindSupports dynamic CSS binding, became one of the most popular Vue 3 versions
2022-02Vue 3 became the default versionOn the vue.js official website and npmvueThe default package version switched from 2 to 3, marking the official dominance of the Vue 3 ecosystem
2022-05Pinia became the official recommendationVuex 5 plans were shelved, Pinia became the officially recommended state management library for Vue 3
2022Vue 3.3Enhanced generic component support, improveddefinePropstype inference, significantly improving TypeScript experience

Continuous Optimization Stage (2023 - Present)

TimeVersionKey features
2023-12Vue 3.4Rewrote the template parser (performance improved ~2x), reactive system optimization (reduced invalid computation triggers),defineModelThe macro officially stabilized (simplifies v-model two-way binding)
2024-09Vue 3.5Reactive Props destructuring officially stabilized (destructure while maintaining reactivity without toRef),useTemplateRefNew APIs, SSR Lazy Hydration
2025 (in development)Vue 3.6Integrated Alien Signals reactive system (dependency tracking memory reduced ~14%), Vapor Mode entered Alpha (completely skips virtual DOM, bundle size reduced from 50KB to ~6KB, 100,000 component mount time ~100ms)

Vapor ModeIs the most important future technical direction for Vue 3: through compile-time static analysis, templates are compiled directly into precise native DOM manipulation code, completely bypassing the virtual DOM creation and diff process. It can coexist with the existing virtual DOM mode and supports progressive migration. Currently only supports<script setup>Composition API; Options API is not applicable.


Vue3's Position Among the Three Major Frameworks

Vue 3, React, and Angular are the three mainstream frameworks in front-end development. Understanding their positions helps make more appropriate technology selections.

Comparison dimensionVue3React 18+Angular 17+
PositioningProgressive framework, officially provides routing and state managementUI library, ecosystem led by communityComplete framework, everything has official solutions
Syntax styleSingle-file components (.vue), intuitive template syntaxJSX, writing HTML in JavaScriptComponents + templates + decorators, high degree of engineering
Learning curveRelatively gentle, template syntax close to HTMLModerate, requires understanding JSX and Hooks mental modelsSteep, many concepts (modules, dependency injection, RxJS)
TypeScriptCore library rewritten in TS, good supportGood, requires @types/reactTypeScript by default, deeply integrated
PerformanceExcellent, fine-grained reactivity, precise updatesGood, React 19 Compiler further optimizedGood, Signals mechanism continuously improving
Applicable scaleSuitable for small-to-medium to large projectsAll scales, mature cases in ultra-large projectsLarge enterprise projects, high team standardization requirements
Chinese market shareHighest, widely used by enterprisesHighRelatively low

In the domestic front-end ecosystem, Vue 3 has the highest usage rate. Component libraries with complete Chinese documentation such as Element Plus and Ant Design Vue have greatly lowered the barrier for enterprise adoption. If your goal is the domestic job market, Vue 3 is one of the frameworks most worth prioritizing.


Vue3's Limitations

Understanding Vue 3's boundaries can help you make more rational technical judgments.

LimitationSpecific manifestationRecommendation
Decision cost of Options API and Composition API coexistingTwo API styles coexist; teams need to agree on unified standards, otherwise code styles will be inconsistentNew projects should uniformly use<script setup> + Composition API
Mental burden of .value for reactive datarefNeeded in scripts.value, automatically unwrapped in templates, beginners easily confusedUse the Volar plugin, IDE will provide hints; no longer a problem once you form the habit
State management complexity for large applicationsPinia's state management support for ultra-large, high-concurrency scenarios is less mature than ReduxUltra-large applications can evaluate Pinia + modular split solutions
Server-side rendering hydration costSSR pages require "hydration", initialization takes longer on low-end devicesVue 3.5 introduced Lazy Hydration, Vue 3.6's Vapor Mode will further improve this
International ecosystem richnessCompared to React, Vue's English community activity and Stack Overflow resources are slightly fewerOfficial documentation is extremely high quality, Chinese documentation is complete, prioritize consulting official documentation
Other extensions