Vue 2 или Vue 3?
Что выбрать composition api или options api?
Vue 3.
Composition API.
Если вам нужен будет Vue 2 для поддержки существующего проекта, то вы сами будете знать ответ на этот вопрос.
Разница между Vue 2 и Vue 3 большая. Это не тот случай, когда надо выучить предварительно предыдущую версию, чтобы лучше и легче понять следующую.
Внимание!
В этом и следующем уроке будет подробно разобран composition api, во всех дальнейших уроках будет использоваться только composition api. Vue 3 и composition api являются предпочтительным выбором для разработки на сегодняшний день. Более производительный, гибкий и удобный способ вести разработку.
Что такое API композиции?
Composition API — это набор API, который позволяет нам создавать компоненты Vue, используя импортированные функции вместо объявления параметров. Это общий термин, охватывающий следующие API
- API реактивности , например ref()и reactive(), который позволяет нам напрямую создавать реактивное состояние, вычисляемое состояние и наблюдателей.
- Хуки жизненного цикла , например onMounted()и onUnmounted(), которые позволяют нам программно подключаться к жизненному циклу компонента.
- Dependency Injection , т.е. provide()и inject(), которые позволяют нам использовать систему внедрения зависимостей Vue при использовании API-интерфейсов Reactivity.
Вот базовый пример компонента, использующего Composition API:
Несмотря на стиль API, основанный на композиции функций, Composition API НЕ является функциональным программированием . Composition API основан на изменяемой, детализированной парадигме реактивности Vue, тогда как функциональное программирование подчеркивает неизменность.
Если вы хотите узнать, как использовать Vue с Composition API, вы можете установить в качестве предпочтения API для всего сайта значение Composition API, используя переключатель в верхней части левой боковой панели, а затем просмотреть руководство с самого начала.
Почему API композиции?
Лучшее повторное использование логики
Основное преимущество Composition API заключается в том, что он обеспечивает чистое и эффективное повторное использование логики в форме составных функций . Он решает все недостатки миксинов , основного механизма повторного использования логики API-интерфейса параметров.
Возможность повторного использования логики Composition API привела к появлению впечатляющих общественных проектов, таких как VueUse , постоянно растущая коллекция компонуемых утилит. Он также служит чистым механизмом для простой интеграции сторонних сервисов или библиотек с сохранением состояния в систему реактивности Vue, например, неизменяемые данные , конечные автоматы и RxJS .
Более гибкая организация кода
Многим пользователям нравится, что мы по умолчанию пишем организованный код с помощью Options API: все имеет свое место в зависимости от того, к какому параметру оно относится. Однако API параметров накладывает серьезные ограничения, когда логика одного компонента превышает определенный порог сложности. Это ограничение особенно заметно в компонентах, которым необходимо решать множество логических задач , что мы наблюдали на собственном опыте во многих производственных приложениях Vue 2.
В качестве примера возьмем компонент проводника папок из графического интерфейса Vue CLI: этот компонент отвечает за следующие логические проблемы
- Отслеживание текущего состояния папки и отображение ее содержимого
- Обработка навигации по папкам (открытие, закрытие, обновление...)
- Обработка создания новой папки
- Переключение отображения только избранных папок
- Переключение отображения скрытых папок
- Обработка изменений текущего рабочего каталога
Исходная версия компонента была написана на Options API. Если мы присвоим каждой строке кода цвет в зависимости от логической задачи, с которой она имеет дело, это будет выглядеть вот так:

Обратите внимание, как код, решающий одну и ту же логическую задачу, вынужден разделяться по разным параметрам, расположенным в разных частях файла. В компоненте длиной в несколько сотен строк понимание и навигация по одной логической проблеме требует постоянной прокрутки файла вверх и вниз, что делает его намного сложнее, чем должно быть. Кроме того, если мы когда-нибудь задумаем извлечь логическую проблему в утилиту многократного использования, потребуется немало усилий, чтобы найти и извлечь нужные фрагменты кода из разных частей файла.
Вот тот же компонент до и после рефакторинга в Composition API

Обратите внимание, как код, связанный с одной и той же логической задачей, теперь может быть сгруппирован: нам больше не нужно переключаться между различными блоками параметров во время работы над конкретной логической задачей. Более того, теперь мы можем переместить группу кода во внешний файл с минимальными усилиями, поскольку нам больше не нужно перетасовывать код, чтобы извлечь их. Это снижение сложности рефакторинга является ключом к долгосрочной простоте сопровождения больших баз кода.
Улучшенный вывод типов
В последние годы все больше и больше разработчиков внешнего интерфейса используют TypeScript, поскольку он помогает нам писать более надежный код, вносить изменения с большей уверенностью и обеспечивает отличный опыт разработки с поддержкой IDE. Однако API-интерфейс Options, первоначально задуманный в 2013 году, был разработан без учета вывода типа. Нам пришлось реализовать абсурдно сложную гимнастику типов , чтобы вывод типов работал с API-интерфейсом Options. Даже несмотря на все эти усилия, вывод типа для Options API все равно может не работать из-за примесей и внедрения зависимостей.
Это побудило многих разработчиков, которые хотели использовать Vue с TS, склониться к Class API на базе vue-class-component. Однако API на основе классов в значительной степени опирается на декораторы ES — функцию языка, которая была предложена только на этапе 2, когда Vue 3 разрабатывалась в 2019 году. Мы посчитали, что слишком рискованно основывать официальный API на нестабильном предложении. С тех пор предложение декораторов претерпело еще одну полную переработку и, наконец, достигло стадии 3 в 2022 году. Кроме того, API на основе классов страдает от повторного использования логики и организационных ограничений, аналогичных API параметров.
Для сравнения, Composition API использует в основном простые переменные и функции, которые, естественно, дружественны к типам. Код, написанный с помощью Composition API, может использовать полный вывод типов без необходимости использования подсказок типа вручную. В большинстве случаев код Composition API будет выглядеть практически одинаково в TypeScript и простом JavaScript. Это также позволяет пользователям простого JavaScript получить выгоду от частичного вывода типа.
Высока производительность
Меньший производственный комплекс и меньшие накладные расходы
Код написан на Composition API, а script setupтакже более эффективен и удобен для минификации, чем эквивалент Options API. Это связано с тем, что шаблон в script setupкомпоненте компилируется как функция, встроенная в ту же область кода script setup. В отличие от доступа к свойствам из this, скомпилированный код шаблона может напрямую обращаться к переменным, объявленным внутри script setup, без использования прокси-сервера между ними. Это также приводит к лучшей минификации, поскольку все имена переменных можно безопасно сократить.
Связь с API параметров
Компромиссы
Некоторые пользователи, перешедшие с Options API, обнаружили, что их код Composition API менее организован, и пришли к выводу, что Composition API «хуже» с точки зрения организации кода. Мы рекомендуем пользователям с таким мнением взглянуть на эту проблему с другой точки зрения.
Это правда, что Composition API больше не предоставляет «ограждения», которые помогут вам поместить ваш код в соответствующие сегменты. Взамен вы получаете возможность создавать код компонента так же, как если бы вы писали обычный JavaScript. Это означает, что вы можете и должны применять любые передовые методы организации кода к коду Composition API, как если бы вы писали обычный JavaScript . Если вы умеете писать хорошо организованный JavaScript, вы также сможете писать хорошо организованный код Composition API.
Options API позволяет вам «меньше думать» при написании кода компонента, поэтому многим пользователям он нравится. Однако, сокращая умственные затраты, он также привязывает вас к предписанному шаблону организации кода без каких-либо выходных люков, что может затруднить рефакторинг или улучшение качества кода в крупномасштабных проектах. В этом отношении Composition API обеспечивает лучшую долгосрочную масштабируемость.
Охватывает ли Composition API все варианты использования?
Да, с точки зрения логики состояния. При использовании Composition API все еще могут понадобиться лишь несколько опций: props, emits, nameи inheritAttrs
Если вы намерены использовать исключительно Composition API (наряду с опциями, перечисленными выше), вы можете сэкономить несколько килобайт в вашем производственном пакете с помощью флага времени компиляции , который удаляет код, связанный с Options API, из Vue. Обратите внимание, что это также влияет на компоненты Vue в ваших зависимостях.
Могу ли я использовать оба API в одном компоненте?
Да. Вы можете использовать Composition API с помощью setup() опции в компоненте Options API
Однако мы рекомендуем делать это только в том случае, если у вас есть существующая кодовая база Options API, которую необходимо интегрировать с новыми функциями/внешними библиотеками, написанными с помощью Composition API
Будет ли API-интерфейс Options deprecated?
Нет, у нас нет никаких планов по этому поводу. API-интерфейс опций — неотъемлемая часть Vue и причина, по которой он нравится многим разработчикам. Мы также понимаем, что многие преимущества Composition API проявляются только в крупномасштабных проектах, а Options API остается надежным выбором для многих сценариев низкой и средней сложности.
Связь с API классов
Мы больше не рекомендуем использовать Class API с Vue 3, поскольку Composition API обеспечивает отличную интеграцию TypeScript с дополнительными преимуществами повторного использования логики и организации кода.
Сравнение с React Hooks
API композиции обеспечивает тот же уровень возможностей логической композиции, что и React Hooks, но с некоторыми важными отличиями.
React Hooks вызываются повторно каждый раз при обновлении компонента. Это создает ряд предостережений, которые могут сбить с толку даже опытных разработчиков React. Это также приводит к проблемам с оптимизацией производительности, которые могут серьезно повлиять на опыт разработки. Вот некоторые примеры
- Хуки чувствительны к порядку вызовов и не могут быть условными.
- Переменные, объявленные в компоненте React, могут быть захвачены с помощью замыкания и стать «устаревшими», если разработчик не может передать правильный массив зависимостей. Это приводит к тому, что разработчики React полагаются на правила ESLint, чтобы гарантировать передачу правильных зависимостей. Однако правило часто недостаточно умно и чрезмерно компенсирует правильность, что приводит к ненужной недействительности и головной боли при возникновении крайних случаев.
- Дорогие вычисления требуют использования useMemo, что опять же требует ручной передачи правильного массива зависимостей.
- Обработчики событий, передаваемые дочерним компонентам, по умолчанию вызывают ненужные дочерние обновления и требуют явной useCallbackоптимизации. Это необходимо почти всегда и опять-таки требует правильного массива зависимостей. Пренебрежение этим по умолчанию приводит к перерисовке приложений и может вызвать проблемы с производительностью, даже не осознавая этого.
- Проблема устаревшего закрытия в сочетании с функциями Concurrent затрудняет определение того, когда запускается часть кода перехватчиков, и делает работу с изменяемым состоянием, которое должно сохраняться во время рендеринга (через useRef), громоздкой.
Для сравнения, Vue Composition API
- Вызывает setup()или script setupкодирует только один раз. Это позволяет коду лучше соответствовать интуиции использования идиоматического JavaScript, поскольку нет необходимости беспокоиться об устаревших замыканиях. Вызовы API композиции также не чувствительны к порядку вызовов и могут быть условными.
- Система реактивности среды выполнения Vue автоматически собирает реактивные зависимости, используемые в вычисляемых свойствах и наблюдателях, поэтому нет необходимости объявлять зависимости вручную.
- Нет необходимости вручную кэшировать функции обратного вызова, чтобы избежать ненужных дочерних обновлений. В целом, детальная система реактивности Vue гарантирует, что дочерние компоненты обновляются только тогда, когда им это необходимо. Ручная оптимизация дочерних обновлений редко вызывает беспокойство у разработчиков Vue.
Мы признаем креативность React Hooks, и это главный источник вдохновения для Composition API. Однако проблемы, упомянутые выше, действительно существуют в его конструкции, и мы заметили, что модель реактивности Vue позволяет их обойти.