Что такое Vue Composition API?

Vue Composition API — это способ организации логики компонентов во Vue.js, представленный начиная с Vue 3. Он предоставляет набор функций, позволяющих декларативно управлять реактивными данными, жизненным циклом и реактивными вычислениями в едином блоке setup() компонента. В отличие от Options API, где логика распределяется по опциям (data, methods, computed, watch), Composition API позволяет объединять связанную логику в одном месте, что особенно полезно в больших компонентах или при повторном использовании логики.

Основная идея Composition API

Composition API основан на функции setup(), которая вызывается до создания компонента и до любого его жизненного цикла. Внутри setup() мы можем:

  • создавать реактивные переменные;

  • определять вычисляемые свойства;

  • отслеживать изменения;

  • использовать жизненные циклы;

  • использовать логические блоки, которые можно выносить в отдельные функции (composition functions).

Пример базового использования

<script setup>
import { ref, computed } from 'vue';
const count = ref(0);
const double = computed(() => count.value \* 2);
function increment() {
count.value++;
}
</script>
<template>
<button @click="increment">
{{ count }} x 2 = {{ double }}
</button>
</template>

Здесь count — это реактивная переменная, созданная с помощью ref(). Вычисляемое значение double обновляется автоматически. Всё определено в одном месте.

ref() и reactive()

  • ref() — создаёт реактивное примитивное значение (число, строку, булев тип). Обращаться к значению нужно через .value.
const message = ref('Hello');
message.value = 'Hi';
  • reactive() — создаёт реактивный объект.
const user = reactive({
name: 'Alice',
age: 30
});
user.age++;

Важно: reactive() нельзя применять к примитивам (числам, строкам).

computed()

computed() возвращает вычисляемое значение, которое автоматически пересчитывается при изменении зависимостей.

const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed(() => \`${firstName.value} ${lastName.value}\`);

watch() и watchEffect()

  • watch() позволяет реагировать на изменения одной или нескольких реактивных переменных.
watch(count, (newVal, oldVal) => {
console.log(\`Изменилось с ${oldVal} на ${newVal}\`);
});
  • watchEffect() автоматически запускается при изменении любых реактивных зависимостей внутри своей функции.
watchEffect(() => {
console.log(\`Счётчик: ${count.value}\`);
});

Жизненный цикл

Для использования хуков жизненного цикла используется специальный набор функций:

import { onMounted, onUnmounted } from 'vue';
onMounted(() => {
console.log('Компонент смонтирован');
});
onUnmounted(() => {
console.log('Компонент размонтирован');
});

Эти функции можно вызывать только внутри setup().

Повторное использование логики (composition functions)

Вынос повторяющейся логики в отдельные функции — одна из ключевых возможностей Composition API.

// useCounter.js
import { ref } from 'vue';
export function useCounter() {
const count = ref(0);
const increment = () => count.value++;
const reset = () => (count.value = 0);
return { count, increment, reset };
}

В компоненте:

<script setup>
import { useCounter } from './useCounter';
const { count, increment, reset } = useCounter();
</script>

Props и context в setup()

Функция setup() получает два аргумента:

setup(props, context) {
// props  реактивный объект с переданными пропсами
// context.attrs  атрибуты
// context.slots  слоты
// context.emit  функция для эмита событий
}

Пример:

setup(props, { emit }) {
const handleClick = () => {
emit('clicked');
};
return { handleClick };
}

defineProps и defineEmits в <script setup>

В <script setup> доступны макросы:

&lt;script setup&gt;
const props = defineProps({
title: String
});
const emit = defineEmits(\['submit'\]);
&lt;/script&gt;

Использование вместе с Options API

Vue 3 позволяет комбинировать Options API и Composition API:

export default {
props: \['msg'\],
setup() {
const count = ref(0);
return { count };
},
mounted() {
console.log('Mounted');
}
}

Однако рекомендуется придерживаться одного подхода в пределах одного компонента.

Отличие от Options API

Aspect Options API Composition API
Структура Разделена по типу (data, methods) Объединена по логике внутри setup()
--- --- ---
Повторное использование Миксины Composition Functions
--- --- ---
Поддержка типов Ограничена Улучшена (особенно с TypeScript)
--- --- ---
Читаемость Хороша для маленьких компонентов Лучше масштабируется при росте
--- --- ---

Типизация с TypeScript

Composition API легко типизируется. Пример:

const count = ref&lt;number&gt;(0);
watch(count, (newVal: number) => {
console.log(newVal);
});

Можно явно указать типы пропсов и возвращаемых значений.

Использование во Vue 2

С помощью @vue/composition-api плагина можно использовать Composition API во Vue 2, но с ограничениями. Это временное решение для миграции.