Composition API — современный способ организации логики во Vue.js, позволяющий создавать более модульный и переиспользуемый код. В отличие от Options API, где данные, методы и жизненные циклы компонента разнесены по разным опциям, Composition API концентрирует связанную логику вместе, используя функции и реактивные примитивы.
Основные примитивы Composition API:
ref() — создание реактивного примитива для простых
значений.reactive() — создание реактивного объекта.computed() — создание вычисляемого свойства,
автоматически отслеживающего зависимости.watch() и watchEffect() — слежение за
изменениями данных.Пример базового использования:
import { ref, reactive, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const state = reactive({ message: 'Hello Vue!' });
const doubled = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, state, doubled, increment };
}
};
Реактивность в Composition API строится на принципе “обёртывания значений”.
ref подходит для примитивов: чисел, строк, булевых
значений.reactive используется для объектов и массивов.Важно помнить, что доступ к значению ref осуществляется
через .value.
const name = ref('Vue');
console.log(name.value); // Vue
name.value = 'Vue 3';
Для объектов, созданных через reactive, доступ
осуществляется напрямую без .value:
const user = reactive({ name: 'Alice', age: 25 });
console.log(user.name); // Alice
user.age++;
computed позволяет определять свойства, которые зависят
от реактивных данных, и автоматически обновляются при их изменении.
const count = ref(2);
const squared = computed(() => count.value ** 2);
console.log(squared.value); // 4
watch отслеживает изменения конкретных реактивных
значений и выполняет побочные эффекты:
watch(count, (newVal, oldVal) => {
console.log(`Count изменился с ${oldVal} на ${newVal}`);
});
watchEffect позволяет автоматически отслеживать все
используемые внутри него реактивные данные:
watchEffect(() => {
console.log(`Текущее значение count: ${count.value}`);
});
Composition API идеально сочетается с TypeScript, так как реактивные примитивы и функции предоставляют строгую типизацию.
Примеры типизации:
import { ref, reactive } from 'vue';
const count = ref<number>(0); // ref с числовым типом
const user = reactive<{ name: string; age: number }>({
name: 'Alice',
age: 25
});
Типизация computed:
import { computed } from 'vue';
const count = ref(5);
const doubled = computed<number>(() => count.value * 2);
Для функций внутри setup можно явно указывать типы
аргументов и возвращаемого значения:
function increment(value: number): number {
return value + 1;
}
Логика, связанная с конкретной функциональностью, часто выносится в composable — отдельные функции, которые возвращают реактивные данные и методы. Это позволяет переиспользовать код в разных компонентах.
Пример composable:
import { ref } from 'vue';
export function useCounter(initial: number = 0) {
const count = ref(initial);
const increment = () => count.value++;
const decrement = () => count.value--;
return { count, increment, decrement };
}
Использование в компоненте:
import { useCounter } from './useCounter';
export default {
setup() {
const { count, increment } = useCounter(10);
return { count, increment };
}
};
Composition API предоставляет функции для работы с жизненным циклом:
onMounted() — вызывается после монтирования
компонента.onUpdated() — вызывается после обновления
компонента.onUnmounted() — вызывается перед удалением
компонента.Пример:
import { ref, onMounted, onUnmounted } from 'vue';
export default {
setup() {
const time = ref(0);
let timer: number;
onMounted(() => {
timer = window.setInterval(() => time.value++, 1000);
});
onUnmounted(() => {
clearInterval(timer);
});
return { time };
}
};
В Composition API доступ к пропсам осуществляется через параметр
setup(props, context):
export default {
props: {
title: String
},
setup(props, { emit }) {
const changeTitle = () => emit('update:title', 'New Title');
console.log(props.title);
return { changeTitle };
}
};
Пропсы автоматически типизируются в TypeScript при использовании интерфейсов:
interface Props {
title: string;
}
export default {
props: {
title: String
},
setup(props: Props) {
console.log(props.title);
}
};
Composition API легко интегрируется с современными библиотеками управления состоянием и маршрутизации.
useRouter() и
useRoute():import { useRouter, useRoute } from 'vue-router';
export default {
setup() {
const router = useRouter();
const route = useRoute();
const goHome = () => router.push('/');
console.log(route.params.id);
return { goHome };
}
};
defineStore и реактивные
состояния напрямую в setup:import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({ name: 'Alice', age: 25 }),
actions: {
setName(newName: string) {
this.name = newName;
}
}
});
Composition API делает работу с состоянием и маршрутами более удобной и типобезопасной.
watch и watchEffect для
побочных эффектов вместо мутаций данных напрямую.Composition API совместно с TypeScript позволяет создавать масштабируемые, поддерживаемые и безопасные приложения на Vue.js.