Если вы работали с Vue 2, то привыкли к Options API — чёткому, но иногда громоздкому разделению логики по опциям data, methods, computed. Vue 3 представил Composition API — революционный подход, который позволяет организовывать код по функциональности, а не по типам опций. Это не просто новый синтаксис, а философия написания более гибких, переиспользуемых и поддерживаемых компонентов. В этой статье мы погрузимся в суть Composition API и разберём практические примеры, которые покажут его мощь.
Что такое Composition API и зачем он нужен?
Composition API — это набор функций, в первую очередь ref, reactive, computed, watch и onMounted, которые можно вызывать внутри функции setup() или в теге <script setup>. Основная цель — логическая композиция: связанная функциональность собирается вместе, а не размазывается по разным секциям компонента.
Ключевое преимущество: Composition API идеально подходит для выделения переиспользуемой логики в композаблы (composables) — самостоятельные функции, которые можно «подключать» к разным компонентам, как конструктор.
Базовый пример: от Options к Composition
Рассмотрим простой счётчик на Options API:
// Options API (Vue 2 стиль)
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
Тот же компонент на Composition API с использованием <script setup> (самый современный синтаксис):
<script setup>
import { ref } from 'vue'
const count = ref(0)
const increment = () => {
count.value++
}
</script>
Обратите внимание: реактивное состояние создаётся с помощью ref, а обращение к значению происходит через .value в JavaScript, но в шаблоне можно писать просто {{ count }}.
Практические примеры композаблов
Настоящая сила Composition API раскрывается при создании собственных композаблов.
Пример 1: Композабл для работы с мышью
// useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'
export function useMouse() {
const x = ref(0)
const y = ref(0)
const update = (event) => {
x.value = event.pageX
y.value = event.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
return { x, y }
}
Использование в компоненте:
<script setup>
import { useMouse } from './useMouse'
const { x, y } = useMouse()
</script>
<template>
<p>Позиция мыши: {{ x }}, {{ y }}</p>
</template>
Пример 2: Композабл для загрузки данных
// useFetch.js
import { ref, onMounted } from 'vue'
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
const loading = ref(false)
const fetchData = async () => {
loading.value = true
try {
const response = await fetch(url)
data.value = await response.json()
} catch (e) {
error.value = e
} finally {
loading.value = false
}
}
onMounted(fetchData)
return { data, error, loading, refetch: fetchData }
}
Композаблы инкапсулируют логику с её собственным жизненным циклом. Это делает код компонентов чище и позволяет легко тестировать логику отдельно от UI.
Работа с реактивностью: ref vs reactive
Vue 3 предлагает два основных способа создания реактивных объектов:
ref— для примитивов и объектов. Требует обращения через.value.reactive— только для объектов. Не требует.value, но теряет реактивность при деструктуризации.
// Использование reactive
import { reactive, toRefs } from 'vue'
const state = reactive({
name: 'Иван',
age: 30
})
// Для деструктуризации с сохранением реактивности используем toRefs
const { name, age } = toRefs(state)
Жизненный цикл в Composition API
Хуки жизненного цикла становятся функциями, которые нужно явно импортировать и вызывать в setup:
import { onMounted, onUpdated, onUnmounted } from 'vue'
onMounted(() => {
console.log('Компонент смонтирован')
})
onUpdated(() => {
console.log('Компонент обновлён')
})
Когда использовать Composition API?
- Сложные компоненты с множеством пересекающихся функций.
- Переиспользование логики между несколькими компонентами.
- Типизация с TypeScript — Composition API обеспечивает превосходную поддержку типов.
- Работа в команде — логическая группировка облегчает понимание кода.
FAQ: Часто задаваемые вопросы
Composition API заменяет Options API?
Нет, это дополнительный, более гибкий подход. Options API остаётся полностью поддерживаемым и отлично подходит для простых компонентов.
Обязательно ли использовать <script setup>?
Нет, это синтаксический сахар. Можно использовать обычную функцию setup(), но <script setup> значительно сокращает boilerplate-код.
Сложно ли перейти с Vue 2 на Composition API?
Переход требует переосмысления организации кода, но базовые концепции реактивности и жизненного цикла остаются. Начинайте с небольших компонентов и композаблов.
Можно ли миксовать Composition и Options API?
Да, в компоненте можно использовать и setup() (Composition), и другие опции, такие как data или methods, но это усложняет понимание. Рекомендуется придерживаться одного стиля.