10 Real‑World Vue 3 Migration Scenarios Every Developer Should Master

This article walks through ten common Vue 3 migration scenarios—parent‑child data flow, two‑way binding, router navigation, context access, slots, component caching, logic reuse, lifecycle hooks, global APIs, and TypeScript integration—providing clear explanations and complete code examples for each case.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
10 Real‑World Vue 3 Migration Scenarios Every Developer Should Master

Scenario 1: Parent‑Child Data Transfer

In Vue 3 the parent still passes props via attributes, but the child declares them with defineProps() inside <script setup>. The example shows a parent component importing ChildView.vue and passing some-prop="parent message", while the child uses defineProps({ someProp: { type: String, required: true } }) and logs the value.

Note: the four macros defineProps, defineEmits, defineExpose and withDefaults can only be used inside <script setup> and are compiled automatically.

Child‑to‑Parent Emission

Vue 2 uses $emit, which is unavailable in <script setup>. Instead, define an emit macro with defineEmits(['someEvent']) and call emit('someEvent', 'child message'). The parent receives the event via @some-event="someEvent".

Parent Access to Child Methods/Properties

Properties and methods are private by default. Expose them with defineExpose({ msg, change }) in the child, then reference the child via a ref in the parent and call child.value.msg or child.value.change() inside onMounted.

Scenario 2: Two‑Way Binding

Vue 2 used v-model or .sync. Vue 3 unifies the syntax to v-model with optional argument names (e.g., v-model:foo, v-model:bar). Internally this maps to :model-value="someValue" and @update:model-value="someValue = $event". The article provides a parent component using v-model="msg" on the child and the child defining defineProps(['modelValue']) and defineEmits(['update:modelValue']) to emit updates.

For input elements, you can bind directly with

:value="modelValue" @input="emit('update:modelValue', $event.target.value)"

or use a computed wrapper that gets/sets modelValue and bind it with v-model="newValue".

Scenario 3: Router Navigation and Parameter Retrieval

In Vue 3 <script setup>, this.$router and this.$route are unavailable. Use the composition API: import useRouter and call

router.push({ path: '/about', query: { msg: 'hello vue3!' } })

. To read parameters, import useRoute and access route.query.msg.

Scenario 4: Accessing the Component Context

The this object is not accessible in <script setup>. Retrieve the instance with getCurrentInstance(), then use const { ctx } = getCurrentInstance() to access the same properties as this. You can also use $parent and $refs from the context.

Vue3 context example
Vue3 context example

Scenario 5: Slot Usage

Vue 2 used the slot attribute and slot‑scope to pass scoped data. Vue 3 replaces this with the v-slot directive. The parent provides a template with v-slot:content="{ msg }", and the child defines a slot name="content" msg="'hello vue3!'". Vue 2.6+ also supports v-slot.

Scenario 6: Caching Route Components

Both Vue 2 and Vue 3 use KeepAlive to cache dynamic components. In Vue 3 you must wrap the routed component inside a RouterView slot:

<RouterView v-slot="{ Component }"><KeepAlive><Component :is="Component"/></KeepAlive></RouterView>

. Lifecycle hooks onActivated and onDeactivated can run logic when a component is cached or restored.

Scenario 7: Logic Reuse

Vue 2 relied on mixins, which can cause naming conflicts. Vue 3 encourages the Composition API. The article shows a useMouse composable that tracks mouse coordinates with ref, registers mousemove listeners in onMounted, and cleans up in onUnmounted. It returns { x, y } for use in any component.

Another composable useRequest abstracts async data fetching: it creates data and error refs, performs axios.get(url), and returns the refs. Components can then render data, error, or a loading state.

Scenario 8: Lifecycle Changes

All Vue 3 lifecycle hooks start with on (e.g., onMounted) and must be imported. beforeCreate and created are removed; synchronous code placed directly in <script setup> runs before component creation.

Destruction hooks are renamed: beforeDestroyonBeforeUnmount, destroyedonUnmounted.

Scenario 9: Global API

In Vue 2 global properties were added to Vue.prototype. In Vue 3 you attach them to the app instance via app.config.globalProperties.$axios = axios. Components access it through

const { proxy } = getCurrentInstance(); proxy.$axios.get('...')

. Global directives and components are also registered on the app instance (e.g., app.directive('focus', { mounted(el) { el.focus() } }) and app.component('CustomComp', CustomComp)). Filters are deprecated; use computed instead.

Scenario 10: Using TypeScript

Add lang="ts" to <script setup>. Props can be typed either by runtime declaration with

defineProps({ foo: { type: String, required: true }, bar: Number })

or by generic type defineProps<Props>(). Default values for generic props are supplied with withDefaults.

Refs can be typed automatically, via the Ref interface, or by passing a generic type to ref<T>(initialValue). Reactive objects infer types from their initial shape, but you can also declare an interface and cast the result: const book: Book = reactive({ title: 'Vue 3 Guide' }).

The article concludes that mastering these Vue 3 APIs and the surrounding ecosystem (Pinia, Vite, etc.) will enable smooth migration from Vue 2.

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.

frontendmigrationTypeScriptComposition APIVue3Script Setup
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

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.