ПроКодинг - Откроем для вас мир IT!

Представьте, что ваш проект на Vue.js превратился в огромный склад, где вещи лежат по категориям: здесь все данные, там - методы, а в другом конце здания - хуки жизненного цикла. Когда компонент маленький, это удобно. Но когда в нем сотни строк кода, вам приходится постоянно бегать между разделами, чтобы понять, как одна переменная влияет на конкретный метод. Именно эту проблему решает переход на Composition API, новый подход к разработке компонентов в Vue 3, который позволяет группировать логику по функциональным признакам, а не по типу опций.

Если вы до сих пор используете Options API, вы не обязаны переписывать всё приложение за одну ночь. Vue 3 спроектирован так, чтобы оба подхода могли сосуществовать. Однако переход на новый стандарт дает реальные преимущества в поддержке кода и типизации. Давайте разберем, как переехать с одного API на другое, не сломав при этом работающий бизнес.

Краткий гид по замене опций

Главная задача при миграции - правильно сопоставить старые разделы компонента с новыми функциями. В Options API логика была жестко распределена по объектам, а в Composition API мы используем импортируемые функции из ядра Vue.

Сопоставление Options API и Composition API
Options API (Vue 2/3) Composition API (Vue 3) Что изменилось?
data() ref(), reactive() Состояние теперь создается через функции реактивности
computed: { ... } computed(() => ...) Вычисляемые свойства стали функциями
methods: { ... } Обычные JS-функции Методы больше не живут в отдельном объекте
mounted(), created() onMounted(), onCreated() Хуки теперь импортируются и вызываются внутри setup
watch: { ... } watch(), watchEffect() Наблюдатели стали более гибкими функциями

Магия <script setup>: почему это стандарт

Если вы только начинаете переезд, забудьте про классическую функцию setup() и переходите сразу к синтаксису <script setup>. Это «сахар», который делает код намного чище. Раньше вам приходилось возвращать все переменные и методы в конце функции setup, чтобы они были доступны в шаблоне. Теперь всё, что объявлено в блоке <script setup>, автоматически попадает в шаблон.

Для работы с пропсами и событиями здесь используются специальные макросы, которые не нужно импортировать:

  • defineProps() - заменяет опцию props. Позволяет четко определить типы данных, которые принимает компонент.
  • defineEmits() - заменяет emits. Теперь вы явно объявляете, какие события компонент может отправить наверх.
  • defineOptions() - появился в Vue 3.3, позволяет задавать имя компонента или настраивать inheritAttrs прямо внутри setup-блока.

Такой подход не только сокращает количество шаблонного кода, но и заметно уменьшает размер итогового бандла, так как компилятор может оптимизировать такие компоненты более эффективно.

Сравнение хаотичного распределения кода и организованных функциональных кластеров Composition API

Практический пример миграции

Допустим, у нас есть компонент счетчика воды. В Options API он выглядел бы так: мы создали cupsOfWater в data, метод drinkCup в methods и следили за изменением через watch. Всю эту логику приходится «размазывать» по всему файлу.

При переезде на Composition API мы создаем ref для счетчика, обычную функцию для логики «питье воды» и вызываем watch прямо рядом с переменной, за которой следим. В итоге вся логика управления водой сосредоточена в одном блоке кода. Если вам понадобится перенести этот функционал в другой компонент, вы просто выносите его в отдельный файл - так называемый composable (композабл). Это и есть главная киллер-фича: переиспользование логики без сложных миксинов, которые в Vue 2 часто приводили к конфликтам имен.

Интеграция с TypeScript: конец эпомтев и ошибок

Одна из главных причин, почему крупные enterprise-проекты переходят на Composition API, - это TypeScript. В Options API типизация была довольно костыльной: вам приходилось описывать типы через сложные интерфейсы или использовать Vue.extend. TypeScript плохо «понимал», что именно возвращает this внутри метода.

В Composition API всё работает на обычных функциях и переменных. Типизация здесь естественна. Если вы создаете ref<number>(0), IDE сразу подскажет вам, что здесь может быть только число. Это сокращает количество багов на этапе разработки и делает автодополнение в VS Code действительно полезным.

Экран монитора с кодом script setup и голографической типизацией TypeScript

Стратегия «мягкого» переезда

Не пытайтесь переписать всё приложение за один спринт. Это прямой путь к бесконечным регрессионным тестам и выгоранию команды. Лучше всего использовать инкрементальный подход:

  1. Новые компоненты - только на Composition API. Это позволит команде привыкнуть к новому синтаксису без риска сломать старый функционал.
  2. Миграция при рефакторинге. Переписывайте старый компонент на Composition API только тогда, когда вам всё равно нужно в него залезть для добавления фичи или исправления бага.
  3. Использование @vue/compat. Если вы переходите с Vue 2 на Vue 3, установите миграционный билд. Он будет выдавать предупреждения в консоли о том, какие части вашего кода больше не поддерживаются и как их исправить.

Помните, что Options API никуда не исчезнет в ближайшее время. Он всё еще поддерживается и работает в Vue 3. Но если вы хотите строить масштабируемую архитектуру, Composition API - единственный путь.

Опасные моменты и подводные камни

Переход не обходится без ошибок. Самая частая проблема новичков - путаница между ref() и reactive(). Если вы используете ref, не забывайте, что в JavaScript-коде доступ к значению идет через .value (например, count.value++), хотя в шаблоне Vue делает это автоматически. reactive() удобен для объектов, но он «теряет» реактивность, если вы попытаетесь деструктурировать его или заменить весь объект целиком.

Также будьте осторожны при миграции с vue-class-component. Классовый подход был популярен в эпоху Vue 2, но в Vue 3 он считается антипаттерном. Переход с классов на функции может потребовать пересмотра всей структуры компонентов.

Нужно ли переписывать все компоненты на Composition API для работы Vue 3?

Нет, не обязательно. Options API полностью поддерживается в Vue 3. Вы можете использовать оба подхода в одном проекте или даже в одном компоненте (через функцию setup). Переписывайте код только тогда, когда это приносит реальную пользу в виде упрощения поддержки или улучшения типизации.

Что лучше: ref или reactive?

Для простых значений (строки, числа, булевы значения) используйте ref(). Для сложных объектов и массивов можно использовать reactive(), но многие разработчики предпочитают ref() даже для объектов, так как он более предсказуем и позволяет легко отслеживать изменения через .value, не теряя реактивность при переприсваивании.

Как заменить миксины (Mixins) в Composition API?

Вместо миксинов теперь используются composables - обычные функции, которые принимают параметры и возвращают реактивные состояния или методы. Это решает проблему «невидимых» источников данных, которая была в миксинах, так как теперь вы явно импортируете и вызываете нужную функцию.

Будет ли приложение работать быстрее после миграции?

Само по себе изменение API не дает колоссального прироста скорости выполнения, но использование <script setup> и удаление лишнего кода Options API (через флаги компилятора) может немного уменьшить размер итогового JS-бандла, что ускорит загрузку страницы.

Можно ли использовать Composition API в Vue 2?

Да, это возможно. В версии Vue 2.7 поддержка Composition API встроена в ядро. Для более старых версий Vue 2 можно использовать плагин @vue/composition-api, который позволяет начать переезд на новый синтаксис еще до обновления самого фреймворка.