Composables: переиспользуемая логика
Учимся выносить реактивную логику из компонента в отдельную функцию-composable, чтобы переиспользовать её где угодно — главная суперсила Composition API.
Composable — функция, которая использует реактивность Vue (
ref,computed, хуки) и возвращает состояние и методы для переиспользования в любом компоненте. По соглашению её имя начинается сuse.
Зачем нужны composables
Допустим, логика счётчика (значение, увеличить, сбросить) нужна в трёх компонентах. Копировать её — плохо. Composition API позволяет вынести логику в обычную функцию и переиспользовать, не дублируя код. Это и есть главное преимущество подхода над Options API.
Пишем useCounter
Composable — это просто функция, которая внутри использует ref и возвращает то, что нужно компоненту:
<!-- composables/useCounter.js -->
<script>
import { ref } from 'vue'
export function useCounter(start = 0) {
const count = ref(start)
function increment() { count.value++ }
function reset() { count.value = start }
return { count, increment, reset }
}
</script>
Любой компонент вызывает её и получает готовую реактивную логику:
<template>
<p>Счёт: {{ count }}</p>
<button @click="increment">+1</button>
<button @click="reset">Сброс</button>
</template>
<script setup>
import { useCounter } from './composables/useCounter'
const { count, increment, reset } = useCounter(10)
</script>
Ключевая мысль про независимость
Каждый вызов useCounter() создаёт своё состояние — composables не делят его между компонентами (если только не выносить ref наружу функции). Проверим это поведение обычным кодом:
function useCounter(start = 0) {
let count = start; // у каждого вызова свой count
return {
increment: () => ++count,
value: () => count,
};
}
const a = useCounter(0);
const b = useCounter(100);
a.increment();
a.increment();
b.increment();
console.log("Счётчик A:", a.value());
console.log("Счётчик B:", b.value());
Вывод:
Счётчик A: 2 Счётчик B: 101
Видно: счётчики a и b независимы — каждый хранит своё состояние. Так же ведут себя и реальные composables на ref.
Соглашение об имени use
Имя composable принято начинать с use (useCounter, useFetch, useMouse). Это не требование синтаксиса, а соглашение сообщества — оно сразу говорит читателю: «это функция с реактивной логикой Vue, её зовут внутри setup».
Что обычно выносят в composables
useFetch— загрузка данных с состояниями loading/error.useLocalStorage— синхронизация ref с localStorage.useMouse— отслеживание позиции курсора.
Итог
- Composable — функция с реактивной логикой, возвращающая состояние и методы.
- Позволяет переиспользовать логику между компонентами без дублирования.
- Каждый вызов создаёт независимое состояние.
- Имя по соглашению начинается с
use.