0Pricing
Frontend Academy · Урок

Composables: повторно используемые функции Composition

Выделяйте реактивную логику в composable-функции с префиксом use, используйте их в разных компонентах и понимайте, чем они отличаются от миксинов.

«Composables: повторно используемые функции Composition» — бесплатный урок Frontend Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.

Что такое компонуемые функции

Компонуемая функция — это функция, использующая хуки Composition API для инкапсуляции и повторного использования логики, связанной с состоянием. Это аналог миксинов в Composition API, но без конфликтов имён и скрытых зависимостей.

Простая компонуемая функция

Вынесите реактивную логику в функцию, название которой начинается с use. Она может использовать ref, computed, watch и хуки жизненного цикла — так же, как setup().

// useCounter.ts
import { ref } from 'vue';

export function useCounter(initial = 0) {
  const count = ref(initial);
  const increment = () => count.value++;
  const decrement = () => count.value--;
  const reset = () => (count.value = initial);
  return { count, increment, decrement, reset };
}

// Usage in any component:
const { count, increment } = useCounter(10);

Компонуемая функция с хуками жизненного цикла

Компонуемые функции могут регистрировать хуки жизненного цикла. Хуки срабатывают относительно компонента, который вызывает компонуемую функцию.

// useOnlineStatus.ts
import { ref, onMounted, onUnmounted } from 'vue';

export function useOnlineStatus() {
  const isOnline = ref(navigator.onLine);

  const update = () => (isOnline.value = navigator.onLine);

  onMounted(() => {
    window.addEventListener('online', update);
    window.addEventListener('offline', update);
  });
  onUnmounted(() => {
    window.removeEventListener('online', update);
    window.removeEventListener('offline', update);
  });

  return { isOnline };
}

Компонуемая функция с асинхронностью (useFetch)

Компонуемые функции отлично подходят для асинхронного получения данных — они инкапсулируют шаблон загрузки, ошибки и данных.

// useFetch.ts
export function useFetch<T>(url: MaybeRef<string>) {
  const data = ref<T | null>(null);
  const loading = ref(true);
  const error = ref<string | null>(null);

  watchEffect(async (onCleanup) => {
    const controller = new AbortController();
    onCleanup(() => controller.abort());
    loading.value = true;
    error.value = null;
    try {
      const res = await fetch(unref(url), { signal: controller.signal });
      data.value = await res.json();
    } catch (e: any) {
      if (e.name !== 'AbortError') error.value = e.message;
    } finally { loading.value = false; }
  });

  return { data, loading, error };
}

Приём refs в качестве параметров

Компонуемые функции могут принимать обычные значения или refs в качестве аргументов с помощью MaybeRef<T> (= T | Ref<T>) и функции unref() для доступа к значению.

import type { MaybeRef } from 'vue';
import { unref } from 'vue';

function useDouble(num: MaybeRef<number>) {
  return computed(() => unref(num) * 2);
}

Компонуемые функции и миксины

Миксины внедряют свойства в компонент без очевидного источника. Компонуемые функции используют явный подход — по возвращаемому значению видно, что именно предоставляет каждая из них. Можно использовать несколько компонуемых функций без конфликтов имён.

Общий доступ к состоянию между компонентами

Если компонуемая функция вызывает ref() внутри себя, каждый компонент, вызывающий её, получает собственное состояние. Чтобы разделить состояние между компонентами, вызывайте ref() на уровне модуля (за пределами функции компонуемой функции).

// Shared state (module-level):
const sharedCount = ref(0);

export function useSharedCounter() {
  // All callers share the same sharedCount
  return { count: sharedCount, increment: () => sharedCount.value++ };
}

Библиотеки компонуемых функций

VueUse (vueuse.org) предоставляет более 200 готовых компонуемых функций: useLocalStorage, useFetch, useDark, useIntersectionObserver и многие другие. Всегда проверяйте VueUse, прежде чем писать решение с нуля.

Тестирование компонуемых функций

Тестируйте компонуемые функции, вызывая их внутри небольшого тестового компонента или используя шаблон mountedApp из @vue/test-utils. Vitest хорошо интегрируется с системой реактивности Vue.

Соглашения об именовании компонуемых функций

Всегда добавляйте префикс use (useAuth, useFetch, useMediaQuery). Сосредотачивайте каждую функцию на одной задаче. Избегайте компонуемых функций, выполняющих слишком много несвязанных задач.

Организация компонуемых функций

Создайте папку composables/. Для каждой компонуемой функции используйте отдельный файл. Индексный файл повторно экспортирует все компонуемые функции. Это соответствует организации пользовательских хуков в проектах React.

Быстрая проверка

В чём ключевое преимущество компонуемых функций перед миксинами Vue?

Итоги: компонуемые функции Vue

Компонуемая функция — это функция с префиксом use, вызывающая хуки Composition API. Каждый вызывающий компонент получает независимое состояние, если только refs не используются на уровне модуля. Принимайте refs или значения с помощью MaybeRef и unref. Регистрируйте хуки жизненного цикла внутри компонуемых функций. Проверяйте VueUse, прежде чем писать собственное решение. Явные возвращаемые значения предотвращают загрязнение пространства имён, характерное для миксинов.

Часто задаваемые вопросы

Урок «Composables: повторно используемые функции Composition» бесплатный?

Да — полный текст урока «Composables: повторно используемые функции Composition» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.

Чему я научусь в уроке «Composables: повторно используемые функции Composition»?

Выделяйте реактивную логику в composable-функции с префиксом use, используйте их в разных компонентах и понимайте, чем они отличаются от миксинов. Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Frontend Academy?

Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Composables: повторно используемые функции Composition»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Frontend Academy?

Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. ref() и reactive()
  2. computed() и watch()
  3. Функция setup() и script setup
  4. Composables: повторно используемые функции Composition
← Назад к Frontend Academy