За обновлениями можно следить в telegram-канале https://t.me/quasiart

Привет.

В этой статье я опишу свой опыт работы с 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-библиотеки и фреймворки рождаются так же быстро, как умирают. Это и плюс, и минус. Но в продуктах с длительным сроком поддержки стоит относиться к этому ответственнее.