Composition API — современный подход к построению компонентов во
Vue.js, введённый в версии 3. Основная цель — сделать код более
организованным, повторно используемым и удобным для
масштабирования. В отличие от Options API, где логика
компонента распределяется по опциям (data,
methods, computed, watch),
Composition API объединяет связанную логику в функции,
называемые композиционными функциями.
Главные элементы Composition API:
setup() — центральная функция
компонента, в которой определяется состояние, методы и реактивная
логика.ref и reactive —
реактивные объекты для хранения состояния.computed — вычисляемые значения на
основе реактивного состояния.watch и watchEffect —
отслеживание изменений данных.setup()setup() вызывается перед созданием
компонента. В неё можно помещать реактивное состояние, функции
и вычисляемые свойства. Важные особенности:
props, context
(attrs, slots, emit).Пример:
import { ref, computed } from 'vue';
export default {
setup(props, { emit }) {
const count = ref(0);
const increment = () => {
count.value++;
emit('update', count.value);
};
const doubled = computed(() => count.value * 2);
return { count, increment, doubled };
}
}
ref и reactiveref используется для примитивов (числа,
строки, булевы значения):
import { ref } from 'vue';
const message = ref('Hello World');
console.log(message.value); // доступ к значению через .value
reactive — для объектов и массивов.
Создаёт глубоко реактивный объект:
import { reactive } from 'vue';
const state = reactive({
user: { name: 'John', age: 30 },
items: [1, 2, 3]
});
state.user.age = 31; // реактивно обновляет все привязанные вычисления и шаблоны
Ключевой момент: ref для примитивов,
reactive для структурированных данных.
computedcomputed создаёт отслеживаемое, кэшируемое
значение на основе реактивных данных:
import { ref, computed } from 'vue';
const count = ref(5);
const doubled = computed(() => count.value * 2);
console.log(doubled.value); // 10
Важное отличие от функций: вычисляемое свойство обновляется только при изменении зависимостей.
watch
и watchEffectwatch позволяет реагировать на
изменения конкретных данных:
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`count изменился с ${oldValue} на ${newValue}`);
});
watchEffect автоматически отслеживает
все реактивные зависимости внутри функции:
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {
console.log(`count сейчас: ${count.value}`);
});
Разница: watch требует явно указать источник,
watchEffect сам определяет зависимости.
Композиционные функции позволяют инкапсулировать логику и повторно использовать её в разных компонентах. Они возвращают реактивные объекты или функции.
Пример:
import { ref } from 'vue';
export function useCounter(initial = 0) {
const count = ref(initial);
const increment = () => count.value++;
const decrement = () => count.value--;
return { count, increment, decrement };
}
Использование:
import { useCounter } from './useCounter';
export default {
setup() {
const { count, increment } = useCounter(5);
return { count, increment };
}
}
В setup() доступ к пропсам через
props:
export default {
props: ['title'],
setup(props) {
console.log(props.title);
}
}
Для вызова событий используется
emit:
setup(props, { emit }) {
const notify = () => emit('custom-event', 'данные');
return { notify };
}
Важно: пропсы readonly, их нельзя изменять напрямую.
В setup() можно работать с slots и
attrs через context:
setup(props, { slots, attrs }) {
return () => (
<div {...attrs}>
{slots.default ? slots.default() : 'Нет слота'}
</div>
);
}
slots.default() — рендеринг содержимого переданного
слота.
Composition API идеально подходит для интеграции с внешними
библиотеками. Пример использования ref с
Pinia:
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useCounterStore = defineStore('counter', () => {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
});
В компоненте:
import { useCounterStore } from './stores/counter';
setup() {
const counter = useCounterStore();
return { counter };
}
ref для примитивов, reactive
для объектов.computed, чтобы
уменьшить лишние вычисления.watch
или watchEffect в зависимости от потребностей.Composition API создаёт мощный и гибкий инструмент для разработки компонентов Vue.js, делая код модульным, читаемым и легко масштабируемым. Он позволяет структурировать приложение вокруг логики, а не только структуры компонентов, что особенно важно в крупных проектах.