Что такое Composition API во Vue и в чем разница с Options API
Что проверяют
Понимаете ли вы, какую проблему решает Composition API, а не только как выглядит setup. Следом обычно спрашивают про разницу ref и reactive, про composables вместо миксинов и про то, что выбрать в новом проекте.
Как отвечать
Оба API работают поверх одной системы реактивности и оба полноценно поддерживаются во Vue 3. Options API не устарел, разница в том, как организован код.
- Options API: компонент описывается объектом с разделами
data,computed,methods,watch, хуками жизненного цикла, доступ к состоянию черезthis. Логика одной фичи размазана по разделам, а переиспользование строится на миксинах с конфликтами имён и неявным происхождением свойств; - Composition API: состояние и логика объявляются функциями
ref,reactive,computed,watch,onMountedи группируются по смыслу. В SFC это<script setup>, где всё объявленное сразу доступно в шаблоне, а пропсы и события задаются черезdefineProps,defineEmits, с версии 3.4 ещё иdefineModel.
Главный выигрыш это composables: функции вроде useFetch или usePagination, которые возвращают реактивное состояние и подключаются в любой компонент. Именно так устроены VueUse и setup-сторы Pinia. Второй выигрыш: типы в TypeScript выводятся сами, без обёрток над this.
Важная деталь для сравнения с React: setup выполняется один раз на экземпляр компонента, а не на каждый рендер. Поэтому нет правил порядка хуков и замыканий на устаревшее состояние, но хуки жизненного цикла нужно регистрировать синхронно во время setup.
Про версии: в Vue 2.7 Composition API встроен, сама ветка Vue 2 перестала поддерживаться в конце 2023 года.
Где спотыкаются
Деструктурируют reactive: const { count } = reactive(state) даёт обычное число без реактивности. Нужны toRefs или отдельные ref.
Забывают .value в скрипте, потому что в шаблоне ref разворачивается автоматически, и получают сравнение объекта с числом.
Вызывают composable с onMounted внутри из обработчика клика или setTimeout. Активного экземпляра компонента в этот момент нет, хук не привяжется, и Vue выдаст предупреждение.