С выходом Vue 3 разработчики получили совершенно новый способ написания компонентов, который называется Composition API. Этот подход был создан, чтобы решить накопившиеся проблемы Options API, особенно заметные в больших и сложных приложениях. Если вы привыкли работать с Options API из Vue 2, поначалу новый синтаксис может показаться непривычным, однако уже после нескольких написанных компонентов его преимущества становятся очевидными. В этой статье мы подробно разберём, что такое Composition API, какие задачи он решает и как с его помощью писать современные компоненты с практическими примерами кода.
Различие между Options API и Composition API
В Options API логика компонента распределяется по нескольким отдельным секциям: data, methods, computed, watch и так далее. Такой подход очень удобен для небольших компонентов, потому что каждая вещь находится на своём месте и структура легко предсказуема. Однако по мере роста компонента одна логическая функциональность, например поиск пользователей, оказывается размазанной по разным секциям — данные в data, функции в methods, наблюдатели в watch. В результате становится трудно отслеживать связанный код и поддерживать его.
Composition API позволяет группировать логику по функциональности, а не по типу опции. Все переменные, вычисляемые значения и наблюдатели, относящиеся к одной задаче, располагаются рядом друг с другом в одном месте. Это значительно упрощает чтение кода и управление крупными компонентами. Кроме того, такую логику можно вынести в отдельные файлы и повторно использовать в других компонентах, что было крайне затруднительно в старом подходе.
Синтаксис <script setup>
Самый современный и лаконичный способ писать компоненты в Vue 3 — это синтаксис <script setup>. Он убирает лишний шаблонный код: вам больше не нужно писать функцию setup(), возвращать значения через return или вручную регистрировать компоненты. Все переменные и функции, объявленные на верхнем уровне, автоматически становятся доступными в шаблоне, что делает код заметно чище и короче.
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
</script>
<template>
<button @click="increment">Нажато: {{ count }}</button>
</template>
Реактивность: ref, reactive, computed и watch
В Composition API для создания реактивного состояния существует две основные функции. Функция ref() используется для примитивных значений (число, строка, булево) и доступ к её значению осуществляется через свойство .value в скрипте, тогда как в шаблоне оно разворачивается автоматически. Функция reactive() предназначена для объектов и делает реактивными все их свойства. На практике многие разработчики предпочитают использовать ref повсеместно из-за единообразия.
import { ref, reactive, computed, watch } from 'vue'
const count = ref(0)
const user = reactive({ name: 'Иван', age: 25 })
// computed — производное значение, зависящее от других
const doubled = computed(() => count.value * 2)
// watch — отслеживание изменений
watch(count, (newVal, oldVal) => {
console.log(`Значение изменилось с ${oldVal} на ${newVal}`)
})
Функция computed() создаёт производное значение на основе других реактивных данных и пересчитывается только тогда, когда меняются её зависимости, что положительно сказывается на производительности. Функция watch() применяется, когда при изменении значения нужно выполнить побочный эффект — например, отправить запрос к API или записать что-то в лог. Эти четыре функции составляют фундамент реактивности в Composition API и используются практически в каждом компоненте.
Переиспользование логики через composable-функции
Самая сильная сторона Composition API — это composable-функции. Composable представляет собой обычную функцию, которая инкапсулирует реактивное состояние и логику, и обычно именуется с префиксом use. Вы помещаете логику внутрь такой функции, а затем вызываете её в любом компоненте, где она нужна. Этот механизм решает проблемы миксинов из Vue 2 и делает код чистым, переиспользуемым и легко тестируемым.
// useCounter.js
import { ref } from 'vue'
export function useCounter(start = 0) {
const count = ref(start)
const increment = () => count.value++
const reset = () => count.value = start
return { count, increment, reset }
}
// В компоненте:
const { count, increment, reset } = useCounter(10)
Когда выбирать тот или иной подход
Composition API не всегда является единственно верным выбором. Для небольших и простых компонентов Options API по-прежнему остаётся удобным и хорошо читаемым, особенно если в вашей команде много разработчиков с опытом Vue 2. Composition API раскрывает себя лучше всего в крупных компонентах со сложной логикой, когда требуется переиспользование кода и строгая типизация при работе с TypeScript. Важно понимать, что оба API можно использовать в рамках одного проекта, поэтому переход может быть постепенным и безболезненным.
Подводя итог, можно сказать, что Composition API является важным шагом в развитии экосистемы Vue, который заметно упрощает управление крупными проектами и переиспользование кода. С помощью синтаксиса <script setup> и composable-функций вы создаёте более чистые, модульные и поддерживаемые компоненты. Если вы начинаете новый проект, мы рекомендуем рассматривать Composition API как выбор по умолчанию.