Отличия Vue 2 и Vue 3

↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Легаси на Vue 2 ещё встречается: ждут знания ключевых отличий и путей миграции.

Объяснение

ОбластьVue 2Vue 3
РеактивностьObject.defineProperty (не видит добавление/удаление свойств, индексы массивов)Proxy (видит всё)
APIOptions APIComposition API + Options
Переиспользованиемиксиныcomposables
Корневых элементоводиннесколько (fragments)
TypeScriptслабая поддержканаписан на TS, отличная типизация
Производительность—быстрее (компилятор с patch flags, hoisting, tree-shaking), меньше бандл
v-modelvalue/input, .syncmodelValue/update:modelValue, несколько v-model, defineModel
Глобальный APIVue.use, Vue.componentcreateApp(), изоляция экземпляров
Фильтры (|)естьудалены (методы/computed)
$listeners, $childrenестьудалены ($attrs включает слушатели)
Event bus ($on/$off)естьудалён (mitt, состояние)
v-if vs v-forv-for приоритетнееv-if приоритетнее
Новые возможности—Teleport, Suspense, <script setup>, Fragment, Emits
СостояниеVuexPinia
РоутерVue Router 3Vue Router 4
СборкаVue CLI/webpackVite
ХукиbeforeDestroy/destroyedbeforeUnmount/unmounted
ПоддержкаEOL с декабря 2023актуальная

Миграция: @vue/compat (режим совместимости) → постепенное устранение предупреждений; обновление экосистемы (Vuex → Pinia, Router 4, Vue Test Utils 2, UI-библиотеки); переход на Vite; переписывание миксинов на composables; затем <script setup> и TS.

// Vue 2                                // Vue 3
new Vue({ render: h => h(App) }).$mount("#app");     createApp(App).mount("#app");
Vue.set(obj, "k", 1);                                  obj.k = 1;      // не нужен

Нюансы и подводные камни

  • Зависимости на Vue 2 (устаревшие UI-библиотеки) блокируют миграцию.
  • Поведение .sync, v-model на компонентах и emit без объявления отличается.
  • В Vue 3 ссылки на this.$refs внутри v-for возвращают массив без гарантии порядка.
  • IE11 не поддерживается.
  • Реактивность объектов создаётся прокси: сравнение === с исходным объектом не работает.

Практика

  1. Составьте план миграции проекта на Vue 2 с оценкой блокеров.
  2. Перепишите миксин в composable.
  3. Найдите использование Vue.set, $listeners, фильтров.

Вопросы с ответами

Связанные темы