Migrating a Legacy Vue 2 App to Vue 3: A Survival Guide
There comes a time in every long-running project's life when a framework upgrade becomes inevitable. Recently, I tackled a beast of a migration: moving an 8-year-old legacy application from Vue 2 to Vue 3. Here is how we survived the process and what you can learn from it.
1. Options API vs. Composition API
The biggest shift is mental. Vue 2’s Options API (data, methods, computed) is comfortable, but the Composition API in Vue 3 offers far better logic reuse. We started by keeping the Options API using the specific build of Vue 3 that supports it, but gradually refactored our most complex components to <script setup>.
// Vue 3 Composition API
<script setup>
import { ref, computed } from 'vue';
const count = ref(0);
const double = computed(() => count.value * 2);
</script>
2. The Event Bus is Dead
Our legacy app relied heavily on a global Event Bus. Vue 3 removed $on, $off, and $once from the instance. We had to replace this pattern with a lightweight library like mitt or move toward a proper state management solution like Pinia.
3. Filters are Gone
We used huge pipe-based filters for text formatting. In Vue 3, we had to convert these to standard utility functions or computed properties. It’s a bit more typing, but vastly easier to debug.
Conclusion
The migration wasn't easy, but the performance gains (thanks to the new Proxy-based reactivity system) were worth it. If you are planning a migration, start with the Migration Build and bite off small chunks at a time.