Composables
↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая
Зачем это на собесе
Composables — способ переиспользования логики; смотрят на именование, реактивные аргументы и очистку.
Объяснение
Composable — функция с префиксом use, инкапсулирующая состояние и логику с реактивностью (вызывается в setup).
// useFetch.ts
export function useFetch<T>(url: MaybeRefOrGetter<string>) {
const data = shallowRef<T | null>(null);
const error = ref<Error | null>(null);
const loading = ref(false);
let ctrl: AbortController | undefined;
async function run() {
ctrl?.abort(); ctrl = new AbortController();
loading.value = true; error.value = null;
try {
const res = await fetch(toValue(url), { signal: ctrl.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
data.value = await res.json();
} catch (e) { if ((e as Error).name !== "AbortError") error.value = e as Error; }
finally { loading.value = false; }
}
watchEffect(run); // повторный запрос при смене url
onScopeDispose(() => ctrl?.abort()); // очистка при уничтожении области
return { data, error, loading, refresh: run };
}
// Использование
const { data: orders, loading } = useFetch<Order[]>(() => `/api/orders?page=${page.value}`);Соглашения:
- Имя
useXxx; файлuseXxx.ts. - Входные параметры: принимайте
MaybeRefOrGetterи читайте черезtoValue— реактивные и обычные значения работают одинаково. - Возвращаемое значение: объект
refs(легко деструктурируется без потери реактивности). - Побочные эффекты и очистка:
onScopeDispose/onUnmounted,watchсonCleanup. - Состояние: локальное (создаётся при каждом вызове) или общее (модульная область — синглтон; для общего лучше Pinia).
- Не принимайте компонентный контекст неявно; хуки жизненного цикла требуют вызова в
setup.
Примеры: useToggle, useDebounce, usePagination, useForm, useAuth, useMediaQuery, useInfiniteScroll.
Composables vs альтернативы:
| Подход | Проблема / особенность |
|---|---|
| Миксины | неявные источники, конфликты имён |
| Renderless-компоненты | лишний слой компонентов |
| Утилиты | без реактивности |
| Pinia | глобальное состояние и DevTools |
Нюансы и подводные камни
- Composable с хуками, вызванный вне
setup/асинхронно послеawait, теряет контекст. - Синглтон-состояние в модуле — проблема для SSR (общее между запросами).
- Не возвращайте
reactive-объект, который придётся деструктурировать. - Тестируйте composables как обычные функции (
withSetupхелпер,mountобёртка).
Практика
- Напишите
useDebouncedRef,usePagination,useLocalStorage. - Сделайте
useFetchс отменой и повторными запросами. - Протестируйте composable с фейковыми таймерами.
Вопросы с ответами
Что такое composable?
Функция, инкапсулирующая реактивную логику и состояние для повторного использования, по соглашению начинающаяся с
use.
Как принять аргумент и реактивным, и обычным?
Использовать
MaybeRefOrGetter<T>и читать черезtoValue.