Философия Composition API

Composition API в Vue.js представляет собой эволюцию архитектурного подхода к построению компонентов, ориентированную на гибкость, повторное использование логики и улучшение читаемости больших приложений. В отличие от Options API, где логика компонента распределяется по заранее определённым опциям (data, methods, computed, watch), Composition API позволяет структурировать код вокруг функциональной логики, объединяя связанные части в единые блоки.


Основные принципы

1. Функциональная организация кода Composition API строится вокруг функций, которые возвращают реактивные данные и методы. Каждая функция может инкапсулировать отдельный аспект поведения компонента:

import { ref, computed } from 'vue';

function useCounter() {
  const count = ref(0);
  const increment = () => count.value++;
  const double = computed(() => count.value * 2);
  return { count, increment, double };
}

Такая организация позволяет выносить логику в отдельные функции, что упрощает тестирование и повторное использование.

2. Реактивность через ref и reactive

  • ref создаёт реактивное примитивное значение:
const message = ref('Привет, Vue');
  • reactive создаёт реактивный объект, подходящий для более сложных структур:
const state = reactive({
  user: 'Иван',
  age: 25
});

Изменения таких значений автоматически отражаются в шаблоне, что делает компонент самодостаточно реактивным.

3. Чистая декларативность и композиция Composition API ориентирован на логическое объединение функциональности, а не на распределение по типам опций. Это особенно полезно при работе с большими компонентами, где смешение методов, вычисляемых свойств и наблюдателей в Options API приводит к трудночитаемому коду.

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    return { count, increment };
  }
}

Здесь весь функционал компонента сосредоточен в одной функции setup, и можно легко вынести часть логики в отдельные функции, сохраняя код структурированным.


Составные функции (Composable Functions)

Composable Functions — это ключевой паттерн Composition API, который позволяет создавать переиспользуемые блоки логики. Они не зависят от конкретного компонента и могут быть использованы в разных местах приложения.

Пример:

import { ref, onMounted } from 'vue';

export function useFetch(url) {
  const data = ref(null);
  const loading = ref(true);

  async function fetchData() {
    loading.value = true;
    const response = await fetch(url);
    data.value = await response.json();
    loading.value = false;
  }

  onMounted(fetchData);

  return { data, loading, fetchData };
}

Использование в компоненте:

import { useFetch } from './useFetch';

export default {
  setup() {
    const { data, loading } = useFetch('https://api.example.com/items');
    return { data, loading };
  }
}

Это создаёт чистый и повторно используемый код, который легко тестировать и модифицировать.


Жизненный цикл и хуки

Composition API предоставляет набор хуков жизненного цикла, которые можно вызывать внутри setup, что делает их более гибкими по сравнению с Options API:

  • onMounted — выполняется после монтирования компонента.
  • onUnmounted — выполняется перед уничтожением компонента.
  • onUpdated — вызывается после обновления компонента.
  • onBeforeMount, onBeforeUpdate, onBeforeUnmount — промежуточные хуки для более тонкого контроля.

Пример использования:

import { ref, onMounted, onUnmounted } from 'vue';

export default {
  setup() {
    const width = ref(window.innerWidth);

    function updateWidth() {
      width.value = window.innerWidth;
    }

    onMounted(() => window.addEventListener('resize', updateWidth));
    onUnmounted(() => window.removeEventListener('resize', updateWidth));

    return { width };
  }
}

Вычисляемые свойства и наблюдатели

Composition API предоставляет функции computed и watch, которые можно использовать гибко и локально:

  • computed создаёт реактивные вычисляемые свойства:
import { ref, computed } from 'vue';

const firstName = ref('Иван');
const lastName = ref('Иванов');

const fullName = computed(() => `${firstName.value} ${lastName.value}`);
  • watch позволяет отслеживать изменения реактивных данных:
import { ref, watch } from 'vue';

const count = ref(0);

watch(count, (newValue, oldValue) => {
  console.log(`Count изменился с ${oldValue} на ${newValue}`);
});

Такая организация даёт возможность точечно управлять реактивностью, без необходимости писать лишний код.


Интеграция с TypeScript

Composition API полностью совместим с TypeScript. Поскольку данные и методы объявляются через функции, типизация становится естественной и строгой:

import { ref } from 'vue';

export default {
  setup() {
    const count = ref<number>(0);

    function increment(): void {
      count.value++;
    }

    return { count, increment };
  }
}

Это устраняет типовые ошибки на этапе компиляции и делает компоненты более предсказуемыми.


Организация больших приложений

Для больших проектов использование Composition API позволяет:

  1. Разделять логику на модули (Composable Functions).
  2. Уменьшать зависимость между компонентами за счёт инкапсуляции логики.
  3. Повышать читаемость кода — связанные функции и реактивные данные находятся рядом.
  4. Облегчать тестирование — функции можно тестировать отдельно от Vue-компонента.

Эта философия отражает переход от декларативного к функциональному стилю программирования в Vue, что делает код более гибким и адаптируемым под сложные задачи.


Composition API не просто альтернатива Options API. Это новая парадигма, ориентированная на чистую композицию, модульность и реактивную декларативность, которая позволяет строить масштабируемые и поддерживаемые Vue-приложения.