https://habrahabr.ru/post/333004/Как говорил М.Т. Калашников: «Просто» сделать в 1000 раз сложнее, чем «сложно». Веб-индустрии понадобилось более половины десятилетия, чтобы прийти от фреймворков-монстров к простой и элегантной конструкции. В IT простота это не только сэкономленные часы работы, а ещё и прозрачная архитектура, выливающаяся в понятный код, меньшее число багов, более быстрое внесение изменений и много других приятных вещей.
В этой статье я проведу сравнение Vue.js с двумя наиболее популярными на данный момент фреймворками: Angular и React. Vue.js намного моложе, поэтому разговор будет прежде всего о нём, об Angular и React грамотные разработчики и так знают. Я бы не начинал этот разговор, если бы Vue не предлагал чего-то действительно стоящего. К счастью это так, и я утверждаю, что в большинстве случаев Vue.js может серьёзно снизить сложность ваших программ, сделать код более лаконичным и выразительным, а отладку — короче и проще. Подробности под катом. Поехали!
Если совсем кратко, то Vue.js — невероятно ненавязчивый фреймворк. Если Angular и React заставляют вас установить целый зоопарк зависимостей, то Vue в минимальной конфигурации не просит от вас абсолютно ничего, кроме собственного js-файла. За это он даёт custom controls, data binding, кастомные директивы и, фактически, все востребованные фишки основных фреймворков. Пример ненавязчивости:
Как выглядит простейшая программа на Vue
Достаточно просто подключить библиотеку, создать контейнер и вызвать конструктор, всё как в старом добром Angular 1, только без его тормозов:
<div id="app">{{ message }}</div>
<script src="https://unpkg.com/vue"></script>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
Это действительно весь код, который вам нужен, это не шутка. Вы можете прямо сейчас скопировать его в редактор, сохранить как something.html и он будет работать. Без плясок с бубном, dependency hell и прочих артефактов современности. Не буду рассказывать как то же самое делается в React или Angular 2+. Про то, как вытащить JSX из React или как писать без TypeScript на Angular 2+ можно написать целую статью.
Почему бы не оставить всё как естьЧем плох TypeScript? Хотя бы тем, что я его не заказывал. В 2005-м году мы боролись за каждый килобайт веса страницы, а сейчас сайты весят по 15 мегабайт и, как будто бы, так и нужно, но это неуважение к пользователю. Я не говорю, что в этом виноват TypeScript, или JSX, или 100500 других побочных технологий, но я хочу сам выбирать, что использовать, а что нет. И чтобы не пришлось платить за этот выбор часами на stackoverflow.
Что касается конкатенации и минификации кода, то для Vue доступно много решений с готовыми сборщиками на том же yeomen (например
github.com/birdgg/generator-vuejs), так же как и для React или Angular. Разница в том, что у вас есть право выбора, использовать их, не использовать, или самому создать сборщик под особенности конкретного проекта.
Custom Controls
Распространённый сценарий развития большинства веб-приложений — увеличение плотности функционала:
- у вас была обычная кнопка, а стала кнопка со индикатором состояния запроса
- была обычная таблица, а стала таблица с сортировкой и фильтрами
- было обычное меню, а стало меню с многократной вложенностью
Если такие компоненты встречаются в приложении один раз — ничего страшного, но чаще бывает, что они раскиданы по разным страницам и в большом количестве. Без custom control такие задачи решаются через боль, мучения и большие затраты времени, с custom controls это делается быстрее в несколько раз. Если вы не сталкивались с такой проблемой — значит у вас не было более-менее серьёзных проектов. Custom controls — это абсолютно must have в современном frontend-программировании. В Angular 1 custom controls отсутствовали (если не считать директивы, которые изначально предназначались совсем для других вещей). В Angular 2+ и React они есть, но достаются довольно дорого. Синтаксис Vue.js очень похож на Angular 2+, но без его ограничений. Немного модифицируем код, представленный выше:
<div id="app">
<ol>
<todo-item v-for="item in list" :todo="item"></todo-item>
</ol>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
});
new Vue({
el: '#app',
data: {
list: ['first item', 'second item']
}
});
</script>
Получилось чуть подлиннее, но у нас здесь custom controls. Custom controls в 20 строчках кода, Карл! При этом сам компонент занял всего 4 строчки. Что это значит на практике: что вы можете делить свой код на компоненты настолько мелко, насколько вам хочется, с минимальными издержками. Если в React создание отдельного компонента — целая история, в завязкой, кульминацией и развязкой, то в Vue это просто несколько секунд. И дело не в этих секундах, а в том, что с большим количеством компонентов у вас будут слабее зависимости и меньше багов.
Это синтетический пример компонента, но в реальных Vue.js раскрывает себя ещё лучше. Мы можем, например:
- вынести весь код компонента в отдельный *.vue файл, включая html, css и javascript
- использовать css-препроцессоры прямо в коде файле компонента, просто указав lang=«scss» или другое
- использовать любые глобальные объекты или получать объекты через import (в React, кажется, на это есть ограничения)
- использовать компоненты только внутри других определённых компонентов, без объявления в глобальной области видимости. Использовать компонент под другим именем, без изменения самого компонента (удобно в случае коллизии имён сторонних компонентов)
и многое другое. Для большинства этих функций нужно подключать сборщик (в документации описан webpack), однако вам дают выбор, использовать Vue на 10%, 50% или на все 100%. Плюс, на мой взгляд, они выбрали самый стабильный и прозрачный сборщик из существующих, но вы можете поменять и его. Вообще Vue поражает своей модульностью и слабосвязанностью, архитектура просто очень хорошо продуманна, что выливается в огромное удовольствие при работе с любой его составляющей. Например:
Создание своих плагинов
Перед тем, как открыть спойлер с кодом остановитесь на минутку и подумайте, как бы вы пропатчили незнакомую библиотеку, если бы захотели добавить туда новый кастомный метод. Подумали? Теперь открывайте ответ:
Как это делается в Vue.js Vue.prototype.$myMethod = function (methodOptions) {
// something logic ...
}
Vue.prototype, Карл! Вам даже не нужно знать
документацию, вы её и так знаете большую её часть на уровне подкорки. Больше никаких странных конфигов, магических свойств, которые нужно указать, чтобы всё заработало. Просто Vue.prototype и имя вашего метода, почему все фреймворки не используют это? Если хотите устанавливать плагин через Vue.use(MyPlugin), то нужно определить метод MyPlugin.install, но это, как и многое в Vue, по вашему желанию.
Общая обстановка
У меня есть большие претензии к команде Angular. Даже не побоюсь сказать, что они фактически убили Angular, создав два совершенно разных продукта и назвав их одним именем. Даже у Vue больше общего с Angular и 1 и 2, чем у этих версий между собой. Возникла огромная путаница в документации, которая ещё не скоро прекратится. Но дело даже не в этом, как гласит один из канонических принципов создания хорошего ПО: делайте программы открытыми для дополнения, и закрытыми для изменения. Подобные радикальные изменения API Angular говорят о том, что продукт изначально был создан проблемным, идеальные программы не нуждаются в изменениях (например /bin/true в linux не переписывалась с 1984 года :)). Конечно Angular это не /bin/true, но реформы — всегда признак проблем.
В чём же причина? Я думаю в том, что как React — это проект для внутренних нужд Facebook, так и Angular 2+ — это проект для внутренних нужд Google. Конкретной компании не требуется поддерживать универсальность. Зачем поддерживать ES6, если в самой компании пишут на TypeScript? Зачем отделять React от зависимостей, если внутри компании он без зависимостей не используется? Конечно пользователи просят, и иногда им идут на встречу, чтобы они совсем не отвернулись, но всё же главная задача этих проектов — не наше с вами счастье, а облегчение найма в эти компании, когда приходит новичёк и уже знает основной стек технологий. Но стек конкретной компании, пусть даже очень крутой, не может являться стандартом для всей отрасли. Отсюда все проблемы с Agular и React. Vue, насколько мне известно, напротив, создавался именно для сообщества, поэтому получился модульным, универсальным, легко адаптируемым под нужные задачи.