Vue.js: что такое, как он устроен и чем отличается от React
Разбираемся с одним из самых популярных фронтенд-фреймворков современности.
Иллюстрация: Colowgee для Skillbox Media
Константин Бирюков
Frontend Developer в LightBox. Увлекается игровой индустрией, любит путешествия, Vue.js и картографические JavaScript-библиотеки.
Vue.js — это JavaScript-фреймворк, который создал разработчик Эван Ю. В 2012 году Эван работал в Google, где успел попробовать Backbone.js и Angular. Именно после этого он решил создать собственный фреймворк — сначала просто как пет-проект.
Популярность обрушилась на Vue.js в 2015 году, и произошло это довольно интересным образом: после твита Тейлора Отвелла, создателя одного из самых популярных PHP-фреймворков Laravel.
«Текущий статус изучения React: слишком сложно. Изучаю Vue.js, потому что он выглядит просто и у него классный сайт».
После этого Vue.js стал не только быстро распространяться в среде Laravel-разработчиков, но и вышел за пределы этого сообщества. Всем, кто интересуется подробностями создания Vue.js, я рекомендую посмотреть документальный фильм Vue.js: The Documentary от Honeypot (в свободном доступе на YouTube).
Сперва Эван Ю выбрал совершенно случайное название для своего будущего фреймворка — Seed.js. Но в момент, когда Эван уже был готов опубликовать пакет в npm, выяснилось, что это имя уже занято.
Тогда Evan решил, что, раз он создаёт View-библиотеку (основа библиотеки — связь отображения и модели), такое название могло бы быть подходящим, но именно в таком написании — view — оно смотрелось бы слишком буквально и скучно. Эван посмотрел переводы слова view на другие языки, и ему приглянулось французское vue. И это имя оказалось свободным в npm.
С тех пор прошло много лет, и Vue.js обрёл огромную популярность во всём мире — теперь это open-source-проект, над которым трудится множество разработчиков из разных стран.
Vue.js очень любим разработчиками. Долгое время фреймворк удерживал первое место по количеству звёзд на GitHub. Сейчас другие проекты сумели побить его достижения, но среди фреймворков он всё так же остаётся лидером.
Vue.js имеет эталонную документацию, которая зачастую приводится в качестве примера того, как в принципе нужно делать официальную доку для какого-либо инструмента. И это правда, работать с ней — одно удовольствие.
Как устроен Vue.js
В основе Vue.js, так же как и React, лежат понятия компонента и состояния. Это уже описано в нашей статье про React.
Что касается организации кода во Vue.js, то, безусловно, самым популярным подходом является создание однофайловых компонентов, где каждый компонент Vue.js — это самодостаточная переиспользуемая единица, отдельный файл с расширением .vue. Такой файл содержит три секции, три отделённых друг от друга элемента: template (представление), script (модель) и style (стили):
Из таких компонентов — строительных блоков, содержащих представление, модель и стили, — составляются полноценные веб-приложения.
Декларативность, реактивность и прогрессивность
Vue.js построен на принципе декларативного отображения данных в DOM с помощью простых шаблонов. Декларативный подход лежит в основе любого фреймворка и зачастую является одной из причин его создания.
Декларативность — это когда мы говорим, что хотим сделать, а фреймворк сам выполняет нужную задачу. Декларативность обычно противопоставляют императивному стилю «ванильного» JavaScript, когда мы вынуждены пошагово описывать каждое действие.
В JavaScript нам необходимо не просто описать суть задачи, но и конкретно, по шагам, прописать всю логику выполнения:
- работать с html‑элементами, обращаясь к ним через id, классы, css‑селекторы;
- навешивать и удалять обработчики события через addEventListener / removeEventListener;
- при изменении данных изменять что-либо в конкретных DOM‑узлах (например, менять текст через textContent) и тому подобное.
Vue.js очень хорош в декларативности. Например, у него есть набор директив, которые очень просто и легко описывают основные операции с html‑элементами: v-bind, v-for, v-if, v-show, v-html и другие.
Декларативность Vue.js
vs
декларативность React
React тоже разделяет философию декларативности, но, как мы увидим, декларативность — понятие относительное. Давайте рассмотрим пример с двумя Vue-директивами: v-for и v-show — и сравним с теми же самыми опциями в React.
Допустим, где-то в коде у нас есть массив объектов articles. Наша задача — вывести у каждого объекта свойство title, а также, в зависимости от логики приложения, показать или скрыть параграф «Данные статьи доступны для скачивания».
Сосредоточимся на логике представления.
Vue-код:
Чтобы отобразить массив, во Vue.js мы используем директиву v-for в теге <li>. В качестве значения указываем "article in articles", где articles — это наш массив, доступный в конкретном компоненте, а article — отдельная статья, элемент на каждой итерации цикла.
Таким образом, мы проходим по всему массиву и выводим свойство "title" для каждой статьи ("article.title"). Значение в двойных фигурных скобках называется интерполяцией и связывает модель с представлением.
Директива v-show фактически «переключает» свойство display с "none" в "initial" и наоборот, в зависимости от значения. В нашем примере предполагается, что, если в наших данных isShow = true, значит, элемент будет отображён, если false — элемент окажется скрытым.
Рекомендуем статью с советами разработчиков о том, как выбрать фреймворк для фронтенда.
Важно помнить, что это не рендеринг элемента по условию (за это отвечает директива Vue.js v-if), директива v-show именно «переключает» свойство display, то есть при рендере компонента наш элемент <p> в любом случае будет присутствовать и займёт своё место в DOM-дереве, а будет ли этот элемент отображён — будет решать значение переменной isShow.
А теперь взгляните, как реализуется та же функциональность на React:
React также является декларативным фреймворком, но мы видим, что в нём куда меньше синтаксического сахара. Да, нам не нужно взаимодействовать с html‑элементами напрямую, и мы всё так же имеем реактивную связь данных и отображения, довольно много логики инкапсулировано.
Однако цикл — это знакомый всем перебор элементов с помощью функции map, а условное отображение элемента использует тернарный оператор. По крайней мере, выглядит всё так, будто мы в чистую html‑разметку вставляем чистые кусочки JavaScript, в целом ничего лишнего и нового для JavaScript-разработчика. Я бы описал философию React так: «Не давать разработчикам слишком много синтаксического сахара».
На этом сравнительном примере можно видеть, насколько Vue.js декларативен. Когда речь идёт о связывании отображения с данными, мы, как разработчики, лишь декларативно «отдаём приказы» (пишем директивы), и Vue делает за нас много работы — как и React. Однако Vue идёт ещё дальше и инкапсулирует даже JS-методы перебора массива и изменения css-свойства "display", заменяя их простым и лаконичным синтаксисом специальных директив.
Vue является реактивным фреймворком: он наблюдает за изменениями в модели и перерисовывает представление по необходимости. Эта функция делает управление состоянием Vue.js довольно простым и интуитивно понятным.
Ещё Vue называют прогрессивным (progressive) фреймворком: его можно использовать в минимальном объёме, установив библиотеку Vue.js, или инкрементно добавлять дополнительные библиотеки, конструируя полноценную инфраструктуру фреймворка. Например, для роутинга обычно используется библиотека Vue Router, для управления состоянием — Vuex или Pinia. Эти библиотеки отлично встроены в экосистему Vue.js и ощущаются её полноценной частью.
В целом экосистема Vue.js выглядит очень целостной. Названные выше Vue Router и Vuex (или Pinia) фактически являются обязательными к изучению. Из других инструментов также стоит изучить Vue CLI для автоматизации множества рутинных задач и Nuxt — фреймворк для приложений на Vue с серверным рендерингом.
На Vue.js можно сделать почти любой проект, который можно реализовать на React/Angular, — впрочем, как и наоборот. Ни один из фреймворков при прочих равных не будет сильно вырываться вперёд. Единственная ситуация, в которой React пока ещё немного впереди — это когда на проекте нужно ещё и мобильное приложение. Тут как раз будет уместен React Native. Хотя Vue делает попытки догнать React и в этом направлении.
Vue.js в компаниях
Вот примеры некоторых зарубежных компаний, которые используют Vue.js в качестве основного фронтенд-фреймворка: GitLab, Alibaba, Nintendo, Upwork, Zoom, Sony, Grammarly, 9GAG и другие. Российский энтерпрайз тоже не отстаёт — на Vue.js плотно сидят те же Ozon и «Спортмастер».
Стоит отметить, что крупные технологические компании имеют множество внутренних проектов, и технологические стеки разных команд могут сильно различаться. Поэтому, хоть многие IT-гиганты вроде Apple и Google используют в качестве основных другие фронтенд-фреймворки, — они также были замечены и в использовании Vue.js. По крайней мере, Vue иногда упоминался в их вакансиях.
Похожая ситуация и в «Яндексе»: React используется повсеместно, а Vue — в отдельных проектах, например в «Едадиле».
Девиз Vue.js — easy to learn and hard to master. Как-то мне довелось поучаствовать в школе Route256 по направлению Vue.js от Ozon. Ozon использует множество разнообразных подходов к написанию Vue-кода: например, фокусируясь на производительности, их разработчики иногда используют функциональные компоненты с render-функциями и «отключением» реактивности, синтаксис JSX (как в React) и многое другое. Но даже внутри Ozon от команды к команде эти подходы могут значительно различаться. Таким образом, несмотря на кажущуюся простоту и низкий порог входа, Vue.js имеет достаточно серьёзную глубину и может быть «переключён» в более низкоуровневый режим.
Популярность Vue.js
Согласно исследованию Stack Overflow, Vue.js входит в топ-5 веб-фреймворков по популярности по итогам 2021 года.
Что касается вакансий, React всё так же остаётся в лидерах. Например: в октябре 2021 года на hh.ru React встречался в требованиях 7636 раз, Angular — 3649 раз, а Vue.js — 2030 раз. В апреле 2022 года на hh.ru React встречался 4921 раз, Angular — 2139 раз, Vue.js — 2320 раз (по всем регионам и странам без фильтров на hh.ru). Если взять период с октября 2021 года по апрель 2022 года, то мы увидим, что Vue.js — единственный фреймворк, количество упоминаний в вакансиях у которого выросло, — по React и Angular мы видим падение.
Заключение
В целом крайне сложно говорить о Vue.js без сравнения с React. Их философия очень похожа, но в деталях много различий. Вот два основных:
- Vue более строг и декларативен. Строгость проявляется в синтаксисе (определённые директивы для каждой задачи), а также в том, как строятся сами компоненты (чёткая структура разделения модели, представления и стилей, особенно при использовании однофайловых компонентов с расширением .vue).
- Vue имеет более «крепкую» инфраструктуру — выбор самых важных библиотек зачастую предопределён.
Такой подход приводит к тому, что новичкам проще писать читабельный код с самых первых дней знакомства с Vue.js. В примере выше код на Vue был написан без знания о существовании тернарного оператора и даже без знания о том, как перебирать элементы в массиве. Нужно было лишь выучить пару простейших директив (v-for и v-show). Остальную работу Vue сделал сам.
На мой взгляд, при прочих равных условиях шанс совершить ошибку во Vue.js меньше, а код его читается проще. При этом важно отметить, что Vue может быть настолько же «свободным» в выражении, как и React. И если глубоко изучить документацию, то можно выйти за привычные рамки — и тогда Vue.js окажется не менее гибким, чем React. И конечно, чем больше и сложнее проект, тем больше вероятность, что понадобится знание продвинутых техник работы с Vue.js и его инструментария.
Документация — не всегда самый простой источник для изучения какого-либо инструмента программирования. Но с Vue это не так. Даже если оставить документацию Vue.js в качестве единственного ресурса для обучения, можно вполне неплохо в этом преуспеть, хотя какие-то дополнительные источники — курсы и видео — могут здорово помочь с пониманием определённых моментов.
Главное — не забывать как можно больше практиковаться, решать задачи с использованием Vue, копаться в документации, пробовать различные подходы и постоянно наращивать сложность.