Master Vue 3: Key Differences, New APIs, and Migration Tips

This article provides a comprehensive guide to Vue 3, covering its performance improvements, tree‑shaking support, Composition API, new global APIs, lifecycle changes, reactive system enhancements, and practical code examples to help developers migrate from Vue 2 to Vue 3 efficiently.

ELab Team
ELab Team
ELab Team
Master Vue 3: Key Differences, New APIs, and Migration Tips

Vue 3 Overview

Vue 3 introduces stronger performance, built‑in tree‑shaking, a Composition API, and several new built‑in components such as Fragment, Teleport, and Suspense, along with better TypeScript support and a custom renderer API.

Why Upgrade?

Modern browsers now support the latest JavaScript features.

The Vue codebase has exposed architectural limitations that the new version addresses.

How Vue 3 Improves Internals

Reactive System: Uses Proxy for faster, more capable reactivity.

Compilation Optimizations: Marks static nodes so the diff only processes dynamic nodes.

Event Caching: Provides cacheHandlers to reuse event callbacks.

Bundle & Size Optimization: Supports on‑demand imports and ES‑module tree‑shaking.

Global API Changes

Vue 2’s global API has been replaced by the app instance API in Vue 3.

import { createApp } from "vue";
import App from "./App.vue";

// Vue 2
new Vue({
  render: h => h(App)
}).$mount("#app");

// Vue 3
createApp(App).use(...).mount("#app");

The following table maps the old Vue 2 globals to their Vue 3 equivalents:

Vue 2

Vue 3 (app)

Vue.config

app.config

Vue.config.productionTip

(none)

Vue.config.ignoredElements

app.config.isCustomElement

Vue.component

app.component

Vue.directive

app.directive

Vue.mixin

app.mixin

Vue.use

app.use

Vue.prototype

app.config.globalProperties

config.isCustomElement

Replaces config.ignoredElements to better express its purpose. It now accepts a function for more flexible matching.

// Vue 2
Vue.config.ignoredElements = [/^ion-/];

// Vue 3
const app = Vue.createApp({});
app.config.isCustomElement = tag => tag.startsWith('ion-');

globalProperties

Replaces Vue.prototype for adding properties accessible in all components.

// Vue 2
Vue.prototype.$http = () => {};

// Vue 3
const app = Vue.createApp({});
app.config.globalProperties.$http = () => {};

Lifecycle Mapping

Vue 2

Vue 3

beforeCreate

setup()

created

setup()

beforeMount

onBeforeMount

mounted

onMounted

beforeUpdate

onBeforeUpdate

updated

onUpdated

beforeDestroy

onBeforeUnmount

destroyed

onUnmounted

activated

onActivated

deactivated

onDeactivated

errorCaptured

onErrorCaptured

New Features

Options API → Composition API (setup function).

Enhanced setup() as the entry point for Composition API.

Composition API Basics

import { toRefs } from 'vue';
export default {
  name: 'demo',
  props: { name: String },
  // setup runs between beforeCreate and created; this is unavailable here.
  setup(props, context) {
    const { name } = toRefs(props);
    console.log(name.value);
    console.log(context.attrs);
    console.log(context.slots);
    console.log(context.emit);
    onMounted(() => {});
  }
};

Key points:

Do not destructure props directly; it will lose reactivity. attrs and slots are proxies and can be safely destructured. this is not available inside setup(); using it causes confusion.

Reactivity: ref and reactive

import { ref, reactive, toRefs } from 'vue';

setup() {
  const counter = ref(0);
  const obj = { a: 1 };
  const objReactive = reactive(obj);
  const add = () => {
    counter.value++;
    objReactive.a++;
  };
  return { counter, objReactive, add };
}

Table comparing ref and reactive:

ref

reactive

Input

Primitive

Object

Return

Reactive ref object

Proxy object

Access .value (auto‑unwrapped in templates)

Direct property access

Watchers

Three main APIs: watch(source, callback) – watches a ref or array of refs. watchEffect(effect, options?) – runs immediately and re‑runs on dependency changes. computed – creates read‑only or writable derived values.

const count = ref(0);
watch(count, (newVal, oldVal) => {
  // ...
});

const plusOne = computed(() => count.value + 1);

watchEffect(() => console.log(count.value));

Additional Notes

Vite 2.0 was released on February 17; see its Chinese documentation at https://cn.vitejs.dev/ .

References include articles from Juejin, CSDN, and Jianshu.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendMigrationJavaScriptreactiveComposition APIVue3
ELab Team
Written by

ELab Team

Sharing fresh technical insights

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.