Привет.
В этой статье я опишу свой опыт работы с Vue.js, обосную его выбор и проведу сравнение с React по некоторым критериям. Сразу поясню, что я не являюсь фанатом какой-либо технологии, фреймворка, языка программирования или парадигмы программирования. Технологии меняются, но что-то важное всегда остаётся (я о котиках, конечно же).
Лирическое отступление, можно пропустить
Так вышло, что в компании, где я работаю, повсеместно используется React уже полтора года. Есть готовая коллекция компонентов и наработки, позволяющие сделать разработку новых проектов быстрее и качественнее. Поэтому Vue.js в обозримом будущем не рассматривается в качестве постоянно использующейся технологии.
Тем не менее, проскакивают проекты, которые не зависят от того, что было разработано ранее, и выбор технологий для них более свободный. Так и вышло в один из спринтов, когда мне предстояло сделать frontend для менеджера печати, который практически не зависел от основной системы автоматизации. Я предложил использовать Vue, и причин этому было несколько:
- Интерес к новой для себя технологии.
- Сбор объективных аргументов за и против.
Последний аргумент связан с тем, что в погоне за хайпом некоторые люди загорелись желанием переписать существующую систему с React на Vue. Естественно, большинство разработчиков было против, так как простое переписывание не только не принесёт существующей пользы бизнесу, но и наоборот — потратит его ресурсы. Советую почитать про кривую Гартнера.
Итак, мне дали свободу действий, и за пару недель я написал интерфейс на Vue. Всё, что здесь описано далее, я постарался сделать максимально объективным. К тому же, моё мнение основывается лишь на одном конкретном приложении. Если где-то читателю покажется, что сравнение по какому-либо критерию натянутое, то уточню, что оно основано лишь на одном конкретном проекте и том, как бы оно было реализовано на React.
Преимущества Vue перед React
Размер бандла
Если не исхищряться, то при прочих равных условиях размер бандла у Vue-приложения получается меньше, чем при использовании React: 140 киб против ~400. Цифры могут отличаться в зависимости от количества сторонних зависимостей, настроек проекта и прочего, но у меня получались такие цифры.
Нативная реактивность
Мне понравилось, что компонент реагировал на простое изменение переменной, хотя в React для этого приходилось использовать setState. Код выглядит лаконичнее.
// React
this.setState({ foo: 'bar' });
// Vue
this.foo = 'bar';
Двунаправленное связывание данных
Во Vue можно запросто связать переменную компонента с полем формы. При изменении переменной поле формы обновится, а при пользовательском изменении поля формы изменится переменная компонента.
Это гораздо проще, чем писать обработчики событий, как принято в React.
classnames из коробки
Когда список классов элемента зависит от некоторых условий, в React приходится либо писать велосипед, либо использовать classnames. Во Vue.js для этого есть встроенные средства.
// React
<div className={classnames('app', isBlurred && 'app--blur')}>
// Vue
<div :class="{ 'app': true, 'app--blur': isBlurred }">
Кэширование computed
Когда в компоненте нужно выводить данные, рассчитываемые динамически, то лучше сделать это с помощью computed, чем вызывать внутри шаблона функцию, как это обычно делается в React. Vue отслеживает изменения зависимостей computed-значения и решает, нужно ли заново производить вычисления.
Хотя для React/Redux тоже есть выход — библиотека reselect .
Prop-types из коробки
Описание входных параметров компонента с указанием их типа и во Vue, и в React очень простое. Но для React почему-то приходится отдельно устанавливать нужный пакет.
Встраивание в существующую вёрстку
Допустим, у нас есть уже существующий сайт, где вёрстка отдаётся сервером. Это может быть обычный статичный сайт, а может и сайт, созданный с помощью какой-нибудь CMS, например, MODX.
Даже в таком случае можно использовать Vue для создания динамических приложений, например, калькуляторов, форм и так далее.
Встраиваем скрипт на страницу: <script src="/assets/templates/js/vue.js?v=2.5.3"></script>
Ну а дальше инициализируем приложение:
new Vue({
el: '#app',
});
Внутри блока #app может быть уже какая-то вёрстка, отданная сервером. Vue-приложение спокойно может её использовать, нужно лишь расставить в нужных местах vue-директивы (v-model, :value, v-for, v-if и т.д.) и прочие синтаксические штуки
Глобальные компоненты
Если в сложных комопнентах часто приходится использовать базовые компоненты (кнопка, поле ввода, иконка и пр.), то надоедает их каждый раз импортировать.
Во Vue 2 и 3 можно зарегистрировать компоненты глобально при инициализации приложения. Это позволяет не отвлекаться на всякие мелочи при разработке. Не встрtчал такого в React.
Недостатки Vue
TypeScript
В проект на React проще внедрить TypeScript. Vue 2 изначально разрабатывался без оглядки на типизацию.
Хотя Vue 3 дружит с TypeScript гораздо лучше, особенно когда я стал использовать Composition API.
Дублирование кода
Для того, чтобы в компоненте использовать другой компонент, мне приходилось сначала импортировать тот компонент, а затем в текущем компоненте указывать, что я хочу его использовать.
import Button from './Button';
export default {
components: {
Button,
},
}
Синонимы
Вместо :v-bind и v-on можно использовать более короткие : и @, но об этом читателю рассказывается только спустя несколько разделов документации. По-моему, стоит придерживаться консистенции и писать всё в сокращённом варианте или хотя бы рассказывать о синонимах в самом начале.
Также меня смутило, что для директив вроде v-model и пр. нет синонима.
Декларативность v-if, v-else-if, v-else
Странно, что в декларативные шаблоны добавили императивные операторы из языков программирования. По-моему, достаточно было реализовать условный рендеринг с помощью v-if, по аналогии с React. А с новыми директивами приходится следить не только за вызовом компонента, но и за соседними и их порядком вызова.
Приоритет директив
Во Vue у разных директив разный приоритет (например, v-if и v-for), что тоже не всегда делает код очевидным для понимания.
Вывод
Было интересно самому пощупать Vue и дать свою оценку независимо от чужих мнений.
Когда я прошу кого-то рассказать о преимуществах Vue, обычно всё сводится к заезженным аргументам, которые невозможно воспринимать серьёзно:
- Низкий порог вхождения.
- Простота.
- Популярность.
Порог вхождения сложно оценить объективно, потому что он зависит от опыта использования других библиотек (React, Backbone, Angular, JSVN и т. д.). Простота изучения так же субъективна. О популярности и говорить нечего: js-библиотеки и фреймворки рождаются так же быстро, как умирают. Это и плюс, и минус. Но в продуктах с длительным сроком поддержки стоит относиться к этому ответственнее.