Какие сложности могут возникнуть при миграции с Vue 2 на Vue 3?
Миграция с Vue 2 на Vue 3 — это не просто обновление зависимости, а переход на новую архитектуру с изменёнными API, компилятором, реактивной системой и внутренними механизмами. В Vue 3 сохранена совместимость со многими особенностями Vue 2 через Migration Build, но полная миграция требует пересмотра подходов к разработке, особенно в больших приложениях.
Ниже перечислены сложности, которые могут возникнуть при миграции, сгруппированные по типам: технические, архитектурные, синтаксические, совместимость с зависимостями и инфраструктурные.
1. Различия в реактивной системе
Vue 2: Object.defineProperty()
-
Ограничения в обнаружении новых свойств (Vue.set(), this.$set()).
-
Проблемы с Array-методами, глубоким слежением.
Vue 3: Proxy
-
Полная поддержка глубоких и вложенных реактивных объектов.
-
Vue.set() и Vue.delete() больше не нужны.
Проблемы при миграции:
-
Старый код с Vue.set не нужен и может быть источником ошибок.
-
Object.freeze делает объект нереактивным в Vue 3.
-
Использование isReactive() / isRef() становится необходимым при работе с внешними библиотеками.
2. API изменения в core
Удалённые/изменённые API:
-
this.$on, this.$off, this.$once — удалены, нужно использовать emits и mitt.
-
keyCode в v-on — больше не поддерживается (@keyup.enter вместо @keyup.13).
-
v-model работает иначе: один modelValue + update:modelValue, больше не value + @input.
<!-- Vue 2 -->
<input :value="value" @input="$emit('input', $event)" />
<!-- Vue 3 -->
<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event)" />
</template>
3. Изменения жизненного цикла
Старые хуки:
- beforeDestroy, destroyed
Новые имена:
- beforeUnmount, unmounted
Проблемы:
-
Все компоненты, использующие старые хуки, не будут вызываться без переименования.
-
Некоторые библиотеки всё ещё используют устаревшие хуки и требуют патчей.
4. Composition API
Vue 3 добавил новую модель через setup() и ref, reactive, computed, watch, и т.д.
Сложности:
-
Переход на Composition API требует полной переработки логики компонентов.
-
Старый Options API продолжает поддерживаться, но при смешивании возникают конфликты типов и тестируемости.
-
Инструменты (eslint, typescript) требуют настройки под setup()-синтаксис.
5. Изменения в директивах
-
v-bind.sync удалён.
-
v-model теперь может быть мультиэкземплярным (с разными аргументами): v-model:title, v-model:checked.
-
v-if и v-for на одном элементе теперь требуют обёртки.
6. Шаблонные особенности
-
v-on.native удалён.
-
Функциональные компоненты должны использовать defineComponent({ functional: true }) больше не поддерживается.
-
$listeners, $attrs, $slots теперь обрабатываются иначе.
7. Обновление зависимости от Vue CLI / Webpack
-
Vue 3 больше не поддерживает старый vue-cli (v4 и ниже).
-
Требуется @vue/cli >= 5 или переход на Vite.
-
Обновление babel, eslint, postcss, typescript, vue-loader, sass-loader, vue-jest — требует ручной настройки.
-
В Vue 3 используется @vue/compiler-sfc, не совместимый с .vue файловой структурой Vue 2.
8. Сторонние библиотеки
Часто несовместимы:
-
vuex@3 не работает с Vue 3 → требуется vuex@4 или pinia.
-
vue-router@3 не работает с Vue 3 → нужен vue-router@4.
-
vuetify@2 — только для Vue 2 → нужен vuetify@3.
-
Старые UI-библиотеки (element-ui, buefy, bootstrap-vue) не обновляются под Vue 3.
-
vee-validate, vue-i18n, axios, vue-test-utils, vue-apollo требуют Vue 3-совместимых версий.
Проблема:
- Некоторые библиотеки не имеют Vue 3 версии — требуется заменить или отказаться.
9. Тестирование и devtools
-
@vue/test-utils@1 — несовместим с Vue 3 → перейти на @vue/test-utils@2.
-
Старые snapshot-тесты ломаются из-за разных шаблонных рендеров.
-
Vue Devtools для Vue 2 и Vue 3 — разные, требуются соответствующие расширения.
10. SSR
Изменения:
-
Vue 3 имеет совершенно новый SSR API.
-
Vue 2 использовал vue-server-renderer, который несовместим с Vue 3.
-
Требуется @vue/server-renderer + ручное создание context + stream поддержка.
11. TypeScript и декларации
-
Vue 3 написан на TypeScript и требует корректных типов.
-
В Vue 2 многие типы были "any", в Vue 3 строже.
-
Ошибки компиляции появляются даже в шаблонах, если lang="ts" не согласован с defineComponent.
12. Рефакторинг компонентов
-
Компоненты с mixins становятся сложнее при переносе на Composition API.
-
extends, inheritAttrs, provide/inject требуют пересмотра.
13. Migration Build и runtime warnings
Vue предоставляет специальную "migration build", в которой старый API работает, но выдаёт предупреждения в консоли.
Проблемы:
-
Не работает в production.
-
Некоторые API всё равно не включены (например, .sync, native).
-
Только временное решение для поэтапной миграции.
14. Миграция шаблонов
-
Старые шаблоны могут использовать устаревшие конструкции, например:
-
v-bind.sync="..." → надо переписать вручную.
-
keyCode → надо заменить на alias (enter, esc).
-
scopedSlots → теперь только slots.
-
15. Разделение на модули и tree-shaking
Vue 3 использует ESM и tree-shaking, что требует:
-
Обновления сборщика (Webpack 5, Vite).
-
Отказа от require() в пользу import.
-
Настройки babel, tsconfig.json и vite.config.ts.
16. Управление глобальными компонентами и плагинами
-
Vue.use() больше не работает — плагины должны быть функцией с app.use(plugin).
-
Глобальные компоненты надо регистрировать вручную в main.ts:
app.component('MyComponent', MyComponent);
17. Сложности при поддержке гибридного проекта (Vue 2 + Vue 3)
-
Комбинация несовместима без использования iframe или micro-frontends.
-
Разные версии vue-loader, babel, eslint, devtools.
-
Возможно дублирование кода и увеличение бандла.
18. Поддержка старого браузера IE11
-
Vue 3 не поддерживает Internet Explorer.
-
При необходимости поддержки IE11 нужно оставаться на Vue 2 или использовать транспиляцию + полифиллы (не рекомендуется).
19. Обратная совместимость unit/functional компонентов
-
functional: true больше не поддерживается в defineComponent().
-
Требуется переписывать такие компоненты вручную.
20. Влияние на производительность и bundle
-
Vue 3 быстрее и легче, но при миграции возможен временный рост размера бандла из-за дублирующих зависимостей (vue@2 + vue@3, если неаккуратно выполнен переход).
-
Старые зависимости могут требовать форков или удаления.