![](https://habrastorage.org/webt/sq/ri/0g/sqri0gcj14y8g_nht9qaxpcyigg.jpeg)
Если вы пытаетесь разобраться, какой из этих двух замечательных фреймворков выбрать, читайте мнение сторонника Vue по этому вопросу, которое я перевел и дополнил.
Переведено при поддержке облачной платформы Mail.ru Cloud Solutions.
Итак, вы разработчик React и решили попробовать Vue. Давайте начнем!
React и Vue — это как Coca-Cola и Pepsi. Многое, что вы можете сделать с помощью React, можно сделать и с помощью Vue. В то же время есть несколько различий, некоторые из которых отражают влияние на Vue фреймфорка Angular.
В этой статье фокус на различиях, поэтому вы сразу окунетесь в мир Vue и увидите пользу.
Как сильно различаются React и Vue?
У React и Vue больше сходств, чем различий:
- это две библиотеки для создания UI;
- обе быстрые и легкие;
- имеют компонент-ориентированную архитектуру;
- используют подход Virtual DOM;
- обе могут подключаться прямо в HTML-файле или в качестве модуля в более сложной системе сборки на Webpack;
- обе имеют отдельные, но широко используемые сторонние библиотеки для роутинга и управления состоянием.
Заметные отличия состоят в том, что Vue обычно использует шаблонные HTML-файлы, а React только JavaScript-файлы. В библиотеке Vue также есть изменяемое (mutable) состояние и автоматическая система перерисовки шаблона под названием «реактивность» (reactivity).
Компоненты
В библиотеке Vue компоненты подключаются с помощью API-метода
.component
, который принимает аргументы id и объекта с переменными определения. Разработчик React, вероятно, заметит знакомые и незнакомые аспекты определения Vue-компонентов в этом коде:Vue.component('my-component', {
//<strong> Свойства</strong> Props
props: [ 'myprop' ],
// <strong>Внутреннее состояние</strong> Local state
data() {
return {
firstName: 'John',
lastName: 'Smith'
}
},
// <strong>Вычисляемые значения </strong>Computed property
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
},
// <strong>Шаблон </strong>Template
template: `
<div>
<p>Vue components typically have string templates.
<p>Here's some local state: {{ firstName }}
<p>Here's a computed value: {{ fullName }}
<p>Here's a prop passed down from the parent: {{ myprop }}
</div>
`,
// <strong>Хук жизненного цикла компонента </strong>Lifecycle hook
created() {
setTimeout(() => {
this.message = 'Goodbye World'
}, 2000);
}
});
Шаблон
Как видно, в компоненте есть свойство
template
, которое представляет из себя строку с HTML-разметкой. Библиотека Vue включает компилятор, который превращает эту строку в рендер-функцию во время исполнения кода. Эти функции рендеринга использует механизм Virtual DOM.Вы можете не использовать свойство
template
, если вместо этого решите создать собственную функцию рендеринга. Вы даже можете использовать JSX-разметку из мира React. Но это было бы странно перейти на Vue и делать так — это как приехать в Италию и отказаться от пиццы…Хуки жизненного цикла
У компонентов Vue методы жизненного цикла похожи на те, что есть у React-компонентов. Например, хук
created
из примера выше запускается тогда, когда готово состояние (state
) компонента, но до того, как компонент прикрепляется к странице. Аналог из мира React — getDerivedStateFromProps
.Но есть одна большая разница: в библиотеке Vue нет аналога реактовского
shouldComponentUpdate
. В этом нет необходимости ввиду наличия в Vue системы реактивности.Перерисовка компонента
Одним из шагов инициализации компонента является просмотр всех его свойств и превращение их в геттеры и сеттеры. Как вы видите, свойство
message
, взятое из первоначальных данных (props
) получило два дополнительных метода — get
и set
:![](https://habrastorage.org/getpro/habr/post_images/136/530/566/13653056638c880c39d72b1e0a307040.png)
Vue присоединяет эти функции, чтобы включить отслеживание зависимостей и уведомления об изменении свойства, когда программа читает или изменяет его.
Изменяемое состояние
Для изменения состояния в Vue вам не нужно вызывать отдельный метод
this.setState
, как это делается в React. Вы просто пишете изменения напрямую:// React
this.setState({ message: 'Hello World' });
// Vue
this.message = 'Hello World';
Когда значение состояния изменено таким образом, запускается метод
set
этого значения (см. выше). Set
запишет новое значение, но у него также есть еще одна задача: он уведомляет библиотеку, что именно это значение поменялось, и та часть верстки, которая зависит от значения этой переменной в состоянии, может нуждаться в перерисовке.Если переменная
message
прокидывается дальше как свойство (prop
) в дочерние компоненты, то библиотека об этом помнит, и дочерние компоненты также будут автоматически перерисованы. Именно поэтому в библиотеке Vue нет нужды в методе жизненного цикла, аналогичном реактовскому shouldComponentUpdate
.Основной шаблон
В отношении главного файла шаблона проекта Vue скорее похож на Angular. Как и в React, шаблон Vue нужно где-то примонтировать непосредственно на странице:
<body>
<div id="root"></div>
</body>
// React
ReactDOM.render('...', document.getElementById('root'));
// Vue
new Vue({
el: '#root'
});
Однако, в отличие от React, вы можете добавлять обычную верстку в этот корневой элемент. Если React при монтировании компонента сотрет всё, что находится внутри элемента
#root
, то Vue сохранит:<div id="root">
<div>You can add more markup to index.html</div>
<my-component v-bind:myprop="myval"></my-component>
</div>
Также есть способ определения шаблонов дочерних компонентов в корневом html-файле через расширения HTML5, такие как x-template или inline-template. Это не считается лучшей практикой, так как отделяет шаблон от определения всего компонента в целом.
Директивы
Снова, как и в Angular, Vue позволяет расширить возможности компонента с помощью логики «директив». Есть специальные HTML-атрибуты с префиксом
v-
, например, v-if
для рендеринга с условиями или v-bind
для привязки выражения к обычному HTML-атрибуту:new Vue({
el: '#app',
data: {
mybool: true,
myval: 'Hello World'
}
});
<div id="app">
<div v-if="mybool">This renders if mybool is truthy.</div>
<my-component v-bind:myprop="myval"></my-component>
</div>
Значение, присвоенное директиве, является JS-выражением, поэтому дальше вы сможете ссылаться на свойства данных, в том числе с помощью тернарных операторов и так далее.
Организация проекта
В библиотеке Vue нет официального эквивалента реактовскому react-create-app, однако есть build, сделанный сообществом Vue-разработчиков: create-vue-app.
Официальная рекомендация для запуска проекта на Vue — это vue-cli. Он может генерировать всё — от простого проекта с одним HTML-файлом до полностью упакованного Webpack + Server-Side Rendering-проекта:
$ vue init template-name project-name
Проекты с одним HTML-файлом
Создатель Vue.js Эван Ю (пхининь You Yu Xi) назвал свой проект «прогрессивным фреймворком», потому что он может быть как масштабирован для сложных приложений, так и упрощен для маленьких приложений.
Конечно, React тоже умеет так. Разница в том, что проекты на Vue обычно используют меньше возможностей ES6 и редко используют JSX, таким образом, им не нужно проходить транспиляцию кода с помощью Babel. Плюс вся библиотека Vue умещается в одном файле, нет отдельных файлов для эквивалентов React типа ReactDOM.
Вот как можно добавить Vue в проект с одним HTML-файлом:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
Важно! Если вы не собираетесь использовать шаблонные строки и, следовательно, не нуждаетесь в компиляторе шаблонов, используйте упрощенную версию библиотеки, в которой нет этих функций, — vue.runtime.js. Она меньше полной примерно на 20 КБ.
Компонент в одном файле
Если вам посчастливилось добавить этап сборки вашего проекта с помощью таких инструментов, как Webpack, вы можете использовать Vue's Single File Components (SFCs, Vue-компоненты в одном файле). Это файлы с расширением
.vue
, они инкапсулируют шаблон компонента, конфигурацию JS и стили в одном файле:<template>
<div class="my-class">{{ message }}</div>
</template>
<script>
export default {
data() {
message: 'Hello World'
}
}
</script>
<style>
.my-class { font-weight: bold; }
</style>
Это, без сомнения, одна из самых замечательных фич библиотеки Vue, потому что вы получаете правильный HTML-шаблон, но JS-логика тут же, рядом, и у вас нет кривого разделения на представление и логику.
Существует Webpack-loader под названием vue-loader, который отвечает за сборку SFCs. В процессе сборки шаблон преобразуется в функцию рендеринга, и это идеальный вариант для использования урезанной сборки vue.runtime.js в браузере.
Redux и остальное
Для Vue есть Flux-ориентированная библиотека управления состоянием под названием Vuex. Она и в этот раз похожа на Redux, но есть некоторые отличия.
Что получает разработчик, переходя с React на Vue?
Чтобы полностью разобраться в вопросе, я дополнил статью и рассказал, когда лучше выбрать React, а когда Vue.
Переход на Vue, скорее всего, упростит ввод новых людей в проект. Шаблоны Vue можно писать прямо в HTML. Также для маленьких проектов необязательно знать последние фичи ES++ и настраивать сборку кода через такие инструменты, как Webpack и Babel. Код для Vue можно писать в jQuery-стиле, то есть прямо в шаблон.
Также Vue имеет удобную систему доставки сообщений об изменениях состояния «из коробки». Разработчикам не нужно заморачиваться с вызовом асинхронного метода
setState
(как в React) или подключать внешние библиотеки для управления доставкой состояния (такие, как Mobx).Наконец, приложения, написанные с помощью Vue, могут быть заметно легче: зачастую нужна будет только сама библиотека или даже ее урезанная версия vue.runtime.js. В то время как современная разработка на React уже практически невозможна без Babel и громоздких бандлов весом до нескольких мегабайт.
С другой стороны, проекты на Vue могут быть слишком сложны, если у вас большое приложение или сложная логика на клиенте. Если верстка вынесена в HTML-шаблон, становится труднее тестировать части приложения. React, который использует только JS-код, дает более широкие возможности переиспользования и расширения кода. Также, если вы пишете на React, вы без особых затрат сможете переиспользовать ваш код при написании приложений для устройств с помощью React-Native. В случае с Vue так не получится.
Поэтому вывод может быть следующим:
- если у вас уже долгоживущий проект, и он написан с помощью одной из библиотек, переход на другую должен быть хорошо обоснован. Действительно серьезных различий между ними мало;
- если же вы запускаете новый проект, то следует ориентироваться на целевые показатели: для более быстрого запуска и более гибкой разработки предпочтительнее Vue, для более сложной бизнес-логики с переиспользованием кода и хорошим покрытием тестами лучше использовать React.
Переведено при поддержке облачной платформы Mail.ru Cloud Solutions.