Skip to Content
VueVue 2 и Vue 3

Vue 2 и Vue 3

Уровень: middle. Глубина реактивности и миграции — senior.

Вопрос

Чем Vue 3 отличается от Vue 2 в повседневном коде?

Короткий ответ

Vue 3 переписал реактивность на Proxy, сделал Composition API основным способом делить логику, разрешил несколько корневых узлов и убрал часть глобального API Vue 2. Приложение создаётся через createApp, а не через new Vue с общим конструктором на всю страницу.

ТемаVue 2Vue 3
РеактивностьObject.defineProperty по уже существующим полям. Новое поле — через Vue.setProxy. Новые поля отслеживаются. Vue.set нет
Описание компонентаOptions API. Composition API только плагиномOptions API жив. Composition API и <script setup> в ядре
Корень шаблонаодин корневой узелфрагменты, несколько корней
v-model компонентаvalue и событие inputmodelValue и update:modelValue. Несколько v-model
Фильтры в шаблоне{{ price | currency }}убраны, вместо них функция или computed
Глобальные APIVue.component, Vue.prototype, шина $onapp.component, app.config.globalProperties. Шина убрана
Сборки и входчасто Vue CLI, один глобальный VueVite, createApp на каждый корень
СостояниеVuexPinia. Vuex 4 умеет работать с Vue 3, официальная рекомендация — Pinia
РоутерVue Router 3, mode: 'history'Vue Router 4, createWebHistory()

Разбор

v-model на компоненте во Vue 3 можно повесить на разные поля: v-model:title и v-model:open. Модификатор .sync из Vue 2 заменён такой записью. Нативный input по-прежнему удобно связывать через v-model, но контракт своего компонента уже другой: проп modelValue, событие update:modelValue.

$listeners слились в $attrs. inheritAttrs: false по-прежнему отключает автоматическую прокидку атрибутов на корень, только корней теперь может быть несколько, и атрибуты нужно вешать явно.

Ключевые хуки переименованы: beforeDestroy стал beforeUnmount, destroyed стал unmounted. В Composition API те же точки доступны как onBeforeUnmount и onUnmounted.

Фильтры, Vue.filter и методы экземпляра $on / $off / $once удалены. Общую шину заменяют внешним эмиттером или, чаще, стором и пропсами.

На что смотрят на senior

Миграция — не «переписать всё на script setup». Options API во Vue 3 поддерживается. Имеет смысл переписывать компонент, когда логика делится между несколькими экранами или когда типы в Options API мешают. Реактивность на Proxy не поддерживает IE11, это сознательный обрыв.

Смотрят, понимаете ли вы последствия фрагментов: директивы и атрибуты, которые раньше попадали на единственный корень, теперь могут некуда сесть. И понимаете ли контракт emits: объявленные события не утекают в $attrs как нативные слушатели.

Типичные ошибки

  • Искать Vue.set во Vue 3.
  • Объявлять v-model как value + input на новом компоненте.
  • Считать, что Composition API обязателен, а Options API выпилен.
  • Тащить фильтры и event bus в новый проект.

Задача

Компонент Vue 3 объявляет props: { value: String } и эмитит input. Родитель пишет <Field v-model="name" />. Почему поле не обновляется?

Показать ответ

Во Vue 3 v-model на компоненте ждёт проп modelValue и событие update:modelValue. Пара value / input — контракт Vue 2.

Родитель меняет name только на update:modelValue. Чужое событие input в эту связь не попадает. Либо переименовать контракт, либо на родителе явно написать :model-value и @update:model-value. С 3.4 то же самое короче через defineModel().

Last updated on