Vue 2에서 3로 마이그레이션 하는 전체적인 틀이 궁금하다면?
2025.11.27 - [Web/Vue] - Vue 2에서 Vue 3로: 공식 마이그레이션 가이드 구조 한 눈에 정리
Vue 2에서 Vue 3로: 공식 마이그레이션 가이드 구조 한 눈에 정리
1. 서론이전까지는 Vue 3 생태계를 익혔다면, 이제부터는 Vue 2에서 Vue 3 마이그레이션을 보도록 하겠습니다.먼저 공식 마이그레이션 가이드가 어떻게 구성되어있는지를 구조적으로 읽어보겠습니
sproutinghye.tistory.com
1. 전역 Vue에서 앱 인스턴스 app으로
Vue 2 코드를 보면 보통 이런 패턴이 많이 나옵니다.
import Vue from 'vue'
import Router from 'vue-router'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Router)
Vue.use(Vuex)
Vue.prototype.$http = axios
Vue.component('BaseButton', BaseButton)
Vue 3로 올라오면 이 패턴이 전부 깨집니다.
Vue 3에서는 더 이상 전역 Vue 인스턴스를 쓰지 않고,
createApp으로 만든 앱 인스턴스(app)에 모든 걸 붙이는 방식으로 바뀌었기 때문입니다.
이번 글에서는 Vue 2의 Global API가 Vue 3에서 어떻게 바뀌었는지,
실제 코드 예시로 Vue.use, Vue.mixin, Vue.prototype, Vue.component 등을 어떻게 옮기는지,
프로젝트에서 어떤 부분을 체크해야 하는지까지 정리해보겠습니다.
2. Vue 2 vs Vue 3: Global API 매핑 표로 정리하기
Vue 3 마이그레이션 가이드에는 Vue 2 Global API와 Bue 3 앱 인스턴스 API의 대응 관계가 표로 정리되어 있습니다.
| Vue 2 Global API | Vue 3 앱 인스턴스 API (app) |
| Vue.config | app.config |
| Vue.config.productionTip | 제거됨 |
| Vue.config.ignoreElements | app.config.compilerOptions.isCustomElement |
| Vue.component | app.component |
| Vue.directive | app.directive |
| Vue.mixin | app.mixin |
| Vue.use | app.use |
| Vue.prototype | app.config.globalProperties |
| Vue.extend | 제거됨 |
Vue 전역을 변이시키던 API들은 전부 앱 인스턴스로 옮겨갔다고 기억하면 됩니다.
3. new Vue → createApp: 앱 생성 코드 변경
[Vue 2 스타일]
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import MyPlugin from './plugins/my-plugin'
Vue.use(MyPlugin)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
[Vue 3 스타일]
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
import MyPlugin from './plugins/my-plugin'
const app = createApp(App)
app.use(router)
app.use(createPinia())
app.use(MyPlugin)
app.mount('#app')
[변화 포인트]
- new Vue({...}) → createApp(App)
- 전역 Vue.use() → app.use()
- Vuex 대신 Pinia를 붙이는 패턴도 같이 적용할 수 있음
=> Global Vue API가 앱 인스턴스 기반으로 변경되었습니다.
4. Vue.use, Vue.mixin, Vue.component 마이그레이션
1️⃣ Vue.use → app.use
[Vue 2]
// plugins/axios.js
import Vue from 'vue'
import axios from 'axios'
Vue.prototype.$axios = axios
이걸 Vue 3에서 그대로 쓰면 동작하지 않습니다.
Vue 3에서는 플러그인은 앱 인스턴스에 등록해야 합니다.
[Vue 3]
// pulgin/axios.js
import axios from 'axios'
export default {
install(app) {
app.config.globalProperties.$axios = axios
}
}
import axiosPlugin from './plugins/axios'
const app = createApp(App)
app.use(axiosPlugin)
2️⃣ Vue.mixin → app.mixin
mixins은 쉽게 말하자면 재사용 모듈입니다.
최상위에서 한 번 섞어 쓰던 전역 mixin도 Vue.mixin → app.mixin으로 옮겨야 합니다.
// Vue 2
import Vue from 'vue'
Vue.mixin({
methods: {
$log(...ars) {
console.log('[LOG]', ...args)
}
}
})
// Vue 3
const app = createApp(App)
app.mixin({
methods: {
$log(...ars) {
console.log('[LOG]', ...args)
}
}
})
다만, 마이그레이션 과정에서 전역 mixin은 가능하면
composable(useXXX)이나 Pinia store로 분리하는 쪽이 더 권장됩니다.
Vue 3 공식 문서와 실전 가이드에서 mixin 남용을 지양하라고 반복해서 언급합니다.
3️⃣ Vue.component → app.component
공통 컴포넌트를 전역 등록하던 코드도 app 인스턴스에 붙여야 합니다.
// Vue 2
import Vue from 'vue'
import BaseButton from '@/components/BaseButton.vue'
Vue.component('BaseButton', BaseButton)
// Vue 3
import BaseButton from '@/components/BaseButton.vue'
const app = createApp(App)
app.component('BaseButton', BaseButton)
Vue 3에서는 가능하면 로컬 등록 또는 auto import 플러그인을 사용하는 것을 권장합니다.
5. Vue.prototype → app.config.globalProperties
아래는 Vue 2에서 전역 헬퍼/라이브러리를 주입하는 가장 흔한 패턴이었습니다.
// Vue 2
Vue.prototype.$formatDate = function (date) { ... }
Vue.prototype.$api = apiClient
Vue 3에서는 app.config.globalProperties를 사용합니다.
// Vue 3
const app = createApp(App)
app.config.globalProperties.$formatDate = (date) => { ... }
app.config.globalProperties.$api = apiClient
만약에 전역 헬퍼가 너무 많다면, 유틸 함수는 그냥 모듈로 import 해서 쓰고
진짜 전역 인스턴스가 필요한 것(API client, analytics 등)만 globalProperties로 올리는 게 좋습니다.
TypeScript를 쓴다면 globalProperties 타입 확장도 같이 해줘야 해서,
정말 필요한 것만 올리자는 쪽으로 정리해두는 게 유지보수에 유리합니다.
6. Global API 트리셰이킹: Vue.netTick → import { nextTick }
Vue 2에서는 Vue.nextTick, Vue.set, Vue.delete 같은 전역 API를 이렇게 쓰곤 했습니다.
Vue.nextTick(() => {
// DOM 조작
})
Vue 3에서는 ESM 기반 트리셰이킹을 위해 전역 API들을 named export로만 제공하는 방향으로 바뀌었습니다.
import { nextTick } from 'vue'
nextTick(() => {
// DOM 조작
})
7. 프로젝트에서 검색해볼 것
- Vue.use(
- 플러그인/라이브러리 등록 위치
- → app.use()로 옮기거나, 플러그인 파일 자체를 Vue 3 스타일로 수정
- Vue.mixin(
- 전역 mixin 사용 위치
- → 반드시 목록화해서, composable/Pinia로 점진적으로 빼낼 후보로 체크
- Vue.component(
- 전역 컴포넌트 등록 위치
- → app.component()로 옮기고, 가능한 곳은 로컬 등록으로 전환
- Vue.prototype
- $axios, $api, $formatDate 같은 전역 프로퍼티
- → app.config.globalProperties 또는 그냥 유틸 import로 대체
- Vue.nextTick, Vue.set, Vue.delete
- → import { nextTick, set, del } from 'vue' 형태로 전환 (필요 시)
정리
- Vue 3의 전역 Vue를 건드리던 것들은 전부 app 인스턴스로 옮겨야 한다.
- Vue.use, Vue.mixin, Vue.component, Vue.prototype 등을 중심으로 어디서 전역을 건드리고 있는지를 먼저 파악해야 한다.
Global API를 제대로 정리하면 플러그인/라우터/상태관리/전역 헬퍼 코드가 Vue 3 구조에 맞게 들어오고
그 위에서 Composition API, <script setup>, Pinia, Router 4를 훨씬 더 자연스럽게 사용할 수 있습니다.
출처
'Framework > Vue' 카테고리의 다른 글
| Vue 3 라이프사이클과 인스턴스 API 변경 정리 (0) | 2025.11.28 |
|---|---|
| Vue 3에서 달라진 v-model과 템플릿 필터 제거 정리 (0) | 2025.11.28 |
| Vue 2에서 Vue 3로: 공식 마이그레이션 가이드 구조 한 눈에 정리 (0) | 2025.11.27 |
| Vue 3 생태계 한 눈에 정리 (0) | 2025.11.27 |
| Vue 3 + Router 4 + Pinia로 미니 SPA 만들기 (0) | 2025.11.26 |