Для начала давайте посмотрим на динамику развития фреймворка, взятого из соответствующего исследования о популярности front-end инструментов:
Вышеприведенный график построен с использованием возможностей проекта NPM Trends. Здесь показано изменение количества загрузок соответствующих пакетов с течением времени. В частности, на нашем графике представлены данные за 6 месяцев 2020 года. Тут хорошо видно то, что React, по исследуемому показателю, значительно обходит конкурентов. А количество загрузок Vue, с другой стороны, постепенно растёт и сейчас находится в районе полутора миллионов.
Это неспроста, ведь Vue в качестве основных преимуществ располагает высокой скоростью, низким порогом вхождения и, что меня больше всего привлекает, лаконичной и приятной структурой. React — это мощный и замечательный инструмент, однако вы вряд ли сможете найти хотя бы 2 одинаково структурированных проекта на этом фреймворке. Да, разработчик способен довольно гибко определять архитектуру и подходы к написанию приложений, но всегда ли это хорошо? Наш сегодняшний герой позволит вам не допускать путаниц и каких-то проблем с тем, когда вы, например, садитесь на новый проект. Давайте посмотрим на Vue в деле. Я буду представлять уже готовый код приложения с пояснениями. Как установить фреймворк и создать приложение вы можете узнать из официальной документации.
<template>
<div id="app">
<h1>To do list</h1>
<AddTodo v-on="add"/>
<hr />
<select v-model="filter">
<option value="all">All</option>
<option value="done">Done</option>
<option value="todo">Todo</option>
</select>
<p v-if="!filterTodos.length">No todo!</p>
<TodoList
v-else-if="filterTodos.length"
v-bind:todos="filterTodos"
@remove="remove"
/>
</div>
</template>
<script>
import TodoList from '@/components/TodoList'
import AddTodo from '@/components/AddTodo'
export default {
data() {
return {
todos: [],
filter: 'all'
}
},
mounted() {
fetch("https://jsonplaceholder.typicode.com/todos?_limit=5")
.then(response => response.json())
.then(json => this.todos = json)
},
components: {
TodoList,
AddTodo,
},
methods: {
remove(id) {
this.todos = this.todos.filter(item => item.id !== id)
},
add(newTodo) {
this.todos.push(newTodo)
}
},
computed: {
filterTodos() {
if (this.filter === 'all') {
return this.todos
}
if (this.filter === 'done') {
return this.todos.filter(item => item.completed)
}
if (this.filter === 'todo') {
return this.todos.filter(item => !item.completed)
}
return []
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
select {
padding: 5px;
margin: 5px 5px 20px 5px;
}
</style>
Перед вами самый “верхний” компонент приложения App.vue, на его примере мы и рассмотрим основные особенности работы.
Сразу замечаем эту самую структуру, о которой так много поговорили в самом начале. В каждой компоненте есть 3 секции, секция с html шаблоном, секция с логикой компоненты в теге script и в самом низу секция со стилями для нашей компоненты. К слову, обязательной является только первая, т.е. компонент может представлять собой просто html шаблон. Также важно отметить то, что в теге template должен быть 1 дочерний элемент.
В целом, даже если ты не знаком с этим инструментом, не сложно прочитать, что тут происходит, давайте посмотрим подробней на блок с логикой.
Как и в React, сначала мы импортируем все необходимые нам компоненты и регистрируем их в поле components. Ничего особенного.
Заметили метод data() который возвращает нам todos и filter. И да, как вы могли догадаться это стейт нашей компоненты, вновь ничего особенного и сложного, но будет интересно как мы с ним будем взаимодействовать.
<template>
<li>
<span v-bind:class="{ done: todo.completed }">
<input
v-bind:checked="todo.completed"
type="checkbox"
v-on:change="todo.completed = !todo.completed"
/>
<strong>{{ index + 1 }}</strong>
{{ todo.title | upper }}
</span>
<button class='rm' v-on:click="$emit('remove', todo.id)">×</button>
</li>
</template>
<script>
export default {
props: {
todo: {
type: Object,
required: true
},
index: Number
},
filters: {
upper(value) {
return value.toUpperCase()
}
},
}
</script>
Выше представлен компонент одной задачи нашего списка Todos, посмотрите как мы принимаем пропсы в поле props, выглядит неплохо, но это можно сделать и по другому, вот компонент всего нашего списка.
<template>
<div>
<ul>
<TodoItem
v-for="(todo, index) of todos"
v-bind:key="todo.id"
v-bind:index="index"
v-bind:todo="todo"
v-on:remove="remove"
/>
</ul>
</div>
</template>
<script>
import TodoItem from '@/components/TodoItem'
export default {
props: ['todos'],
components: {
TodoItem
},
methods: {
remove(id) {
this.$emit('remove', id)
}
}
}
</script>
Вы можете делать как вам понравится.
Вернемся к App.
Далее метод mounted() — это равносильно уже знакомому нам из React componentDidMount, т.е. в данном случае при рендере компоненты у нас выполняется запрос на https://jsonplaceholder, а результат запроса мы записываем в стейт с помощью обычного оператора присваивания:
this.todos = json
Да, именно там мы меняем стейт в Vue, удобно правда?
Поле methods — то место, где мы объявляем все наши методы, которые мы хотим использовать в дальнейшем.
Более интересная фишка фреймворка — computed. Это вычисляемые свойства компоненты, в которой мы можем обработать переменные нашего стейта и использовать эти данные как сами переменные. В данном случае мы обрабатываем массив наших todos по с помощью filter переменной, из select (см template секцию), чтобы показывать либо те задачи, которые мы выполнили, либо те, что только предстоит выполнить, либо все сразу.
Кстати о переменной filter, как она меняется в зависимости от выбранного option? В React мы бы сделали стейт и контролируемый элемент, но это вам не React. v-model атрибут в select-те берет это все на себя и делает под капотом. Все, теперь изменяя опцию в селекте, мы меняем наш стейт, круто, правда?
Посмотрим на еще несколько основных атрибутов, которые нам предлагает использовать Vue.
v-on — позволяет нам отловить события элемента и обработать их, в данном случае это наше событие на добавление у компонента AddTodo, но мы можем также ловить и классические события, например клик по кнопке. Также для сокращения мы можем использовать знак собаки, как например @remove.
v-if и v-else-if — механизм того, как мы можем показывать компонент в зависимости от указанного условия.
v-bind — один из самых важных атрибутов, он позволяет “зарегистрировать” какое-либо свойство для компонента, например, объявить класс или передать пропсы. Выше вы можете увидеть много случаев использования этого атрибута.
Вы также могли заметить интересный момент:
v-for="(todo, index) of todos" — это всего-навсего знакомый нам .map для массива todos, но на Vue лад.
Я постарался максимально кратко показать основные принципы работы Vue, настоятельно рекомендую скачать и посмотреть на полный код приложения.
Что хочется сказать по итогу, меня очень зацепила простота и лаконичность этого инструмента, он очень много берет на себя, давая нам максимально комфортную работу, при этом абсолютно не проседая в производительности.
Всегда полезно отвлечься от уже приевшегося инструмента и пощупать что-то новое, я надеюсь эта статья помогла вам в этом.
Не бойтесь пробовать что-то новое, развивайтесь и помните, что лучший инструмент — это не тот, что дает хорошую структуру приложению, быстрее или занимает топ по скачиваниям, а тот, что позволяет именно вам получать максимальное удовольствие от работы, благо сейчас зная хотя бы 1 из популярных фреймворком для front-end разработки — вы уже не пропадете.
Успехов!
Djeux
Интересно, когда прекратят называть React фреймворком, когда у них на основной странице большим шрифтом написано «A JavaScript library for building user interfaces»
DaturInnoxia
Меня умиляет, как реакт-разработчики борятся за право называть реакт библиотекой, когда сами же, тут же после скачивания своей «библиотеки» закачивают пачку других реакт-библиотек, чтобы наконец получить весь тот функционал, который как раз таки и делает твою библиотеку фреймворком.
MaZaAa
React + MobX + Typescript и всё, теперь это человеческий и реактивный инструмент.
В отличии от ущербной связки react + redux(effecor и т.д и т.п.) или вообще голый react.
Djeux
Не являюсь react разработчиком. Использую его исключительно для создания интерактивных интерфейсов на некоторых страницах дабы не городить спагетти jquery кода.
То что можно обвесить исходный пакет кучей других пакетов и собрать из этого свой фреймворк еще не делает изначальный пакет фреймворком. С таким успехом можно и jquery отнести туда же.
barkalov
Да, да, и не вздумайте назвать Angular фреймворком! У них на сайте большим шрифтом написано: "The modern web
developer's platform".
shuron
И в чем проблема?
barkalov
Я не знаю как вам ответить.
shuron
ну посколько там полно тулинга и технологий набор. то в поне платформа.
barkalov
А React, как считаете?