Что такое 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> доступны макросы:
<script setup>
const props = defineProps({
title: String
});
const emit = defineEmits(\['submit'\]);
</script>
Использование вместе с 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<number>(0);
watch(count, (newVal: number) => {
console.log(newVal);
});
Можно явно указать типы пропсов и возвращаемых значений.
Использование во Vue 2
С помощью @vue/composition-api плагина можно использовать Composition API во Vue 2, но с ограничениями. Это временное решение для миграции.