Composables представляют собой функции, которые инкапсулируют повторно используемую реактивную логику и могут быть легко подключены в компоненты Vue. Этот подход является ключевой частью Composition API и позволяет строить масштабируемые, модульные и тестируемые приложения.
Composables — это обычные функции JavaScript, в которых используются
реактивные переменные (ref, reactive) и
вычисляемые свойства (computed). Их основная цель —
отделение логики от компонентов и повторное использование кода.
Пример простого composable:
import { ref, computed } from 'vue';
export function useCounter() {
const count = ref(0);
const increment = () => {
count.value++;
};
const decrement = () => {
count.value--;
};
const double = computed(() => count.value * 2);
return {
count,
increment,
decrement,
double
};
}
В этом примере useCounter инкапсулирует логику счетчика.
Любой компонент может подключить этот composable и использовать его
состояние и методы без дублирования кода.
Одно назначение Каждый composable должен решать
конкретную задачу. Например, useFetch для запросов к API
или useFormValidation для проверки форм.
Возвращение только нужного Не следует возвращать лишние переменные или методы. Только те, которые необходимы для работы компонента.
Не зависеть от компонента Composable должен быть
независимым. Он не должен напрямую обращаться к DOM или жизненному циклу
компонента, за исключением хуков Composition API
(onMounted, onUnmounted и т.д.).
Использование реактивности Основная сила composables заключается в возможности использовать реактивные переменные и вычисляемые свойства для синхронизации состояния.
import { ref } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(false);
const fetchData = async () => {
loading.value = true;
try {
const response = await fetch(url);
if (!response.ok) throw new Error('Ошибка сети');
data.value = await response.json();
} catch (err) {
error.value = err;
} finally {
loading.value = false;
}
};
return {
data,
error,
loading,
fetchData
};
}
Этот composable можно использовать в любом компоненте для выполнения запросов и управления состоянием загрузки и ошибок.
import { ref, watch } from 'vue';
export function useLocalStorage(key, initialValue) {
const storedValue = localStorage.getItem(key);
const data = ref(storedValue ? JSON.parse(storedValue) : initialValue);
watch(data, (newValue) => {
localStorage.setItem(key, JSON.stringify(newValue));
}, { deep: true });
return data;
}
Этот подход позволяет автоматически синхронизировать реактивные
переменные с localStorage.
Composables могут использовать хуки жизненного цикла для выполнения действий на определённых этапах существования компонента:
import { onMounted, onUnmounted, ref } from 'vue';
export function useWindowWidth() {
const width = ref(window.innerWidth);
const updateWidth = () => {
width.value = window.innerWidth;
};
onMounted(() => {
window.addEventListener('resize', updateWidth);
});
onUnmounted(() => {
window.removeEventListener('resize', updateWidth);
});
return width;
}
Использование таких composables позволяет компоненту оставаться чистым и сосредоточенным на отображении данных.
Папка composables Все composables
рекомендуется хранить в отдельной папке проекта, например,
src/composables.
Именование По соглашению функции composables
начинаются с префикса use, например: useAuth,
useTheme, useForm.
Разделение логики Если функционал становится слишком большим, его стоит разделять на несколько composables для повышения читаемости и тестируемости.
Composables отлично сочетаются с глобальными хранилищами состояния. Вместо прямого подключения состояния в компонент, можно создать composable, который оборачивает работу со стором:
import { computed } from 'vue';
import { useStore } from 'vuex';
export function useCart() {
const store = useStore();
const items = computed(() => store.state.cart.items);
const total = computed(() => store.getters['cart/totalPrice']);
const addItem = (product) => {
store.commit('cart/addItem', product);
};
return { items, total, addItem };
}
Такой подход упрощает тестирование и повторное использование бизнес-логики.
Использование composables позволяет создавать приложения, где логика четко разделена, компоненты остаются компактными, а код легко поддерживается и расширяется.