Я создал ту же программу в React и Vue. Вот отличия.

1656551905 ya sozdal tu zhe programmu v react i vue vot

автор Сунил Сандху

Воспользовавшись Vue на моем нынешнем рабочем месте я достаточно ясно понимал, как это все работает. Однако мне было интересно узнать, какой была трава по ту сторону забора – трава в этом сценарии была React.

Я прочитал документы React и просмотрел несколько обучающих видео, и, хотя они были замечательными, я действительно хотел знать, насколько они отличаются Отреагировать был из Vue.

Под «разным» я не имел в виду вещи, например, были ли они оба виртуальные DOMS или как они отображали страницы. Я хотел, чтобы кто-то удосужился объяснить код и рассказать мне, что происходит! Я хотел найти статью, которая бы уделила время, чтобы объяснить эти отличия, чтобы кто-то новый Vue или Отреагировать (или веб-разработка в целом) может лучше понять отличия между ними.

Но я не смог найти ничего, что боролось бы с этим. Так что я понял, что мне придется идти дальше и построить это самому, чтобы увидеть сходство и отличие. Делая это, я думал, что задокументирую весь процесс, чтобы наконец-то появилась статья об этом.

gxU7ZAu4Ey12iGnSlpGwYH6i83ncsHcmIEDj
Кто носил его лучше?

Я решил попытаться создать достаточно стандартную программу To Do, позволяющую пользователю добавлять и удалять элементы из списка. Обе программы были созданы по умолчанию CLI (create-react-app для Отреагироватьи vue-cli для Vue). CLI, кстати, означает интерфейс командной строки. ?

Во всяком случае, это вступление длиннее, чем я ожидал. Давайте начнем с краткого обзора, как выглядят две программы:

V9NdEyLFZvFCGDQ731P892-lTF3lcXP9laP1
Vue против React: Непреодолимая сила встречается с недвижимым объектом

Код CSS для обеих программ абсолютно одинаков, но есть отличия в том, где они расположены. Имея это в виду, давайте далее посмотрим на структуру файлов обеих программ:

GV3G8hb9X8mA-vnRcfRpboA59nVO46ZTIknR
Кто носил его лучше?

Вы увидите, что их структуры тоже почти идентичны. Единственное отличие здесь заключается в том, что программа React имеет три файла CSS, в то время как программа Vue не имеет ни одного. Это потому, что в приложении create-react-app, компонент React будет иметь сопроводительный файл для хранения стилей, тогда как Vue CLI использует всеобъемлющий подход, когда стили объявляются внутри фактического файла компонента..

В конце концов они оба достигают одного и того же, и нельзя сказать, что вы не можете продолжить и структурировать свой CSS по-разному в React или Vue. Это действительно сводится к личным предпочтениям — вы услышите много обсуждений от сообщества разработчиков по поводу того, как должен быть структурирован CSS. Мы просто придерживаемся структуры, изложенной в обоих CLI.

Но прежде чем идти дальше, давайте быстро посмотрим, как выглядят типичные компоненты Vue и React:

OYJ9J1mD7ENdqSy0d66zRGSRivznwiHyi1HH
Vue слева. Реагируйте вправо

Теперь это не так, давайте перейдем к мельчайшим деталям!

Как мы изменяем данные?

Но прежде, что мы вообще подразумеваем под «мутацией данных»? Звучит немного технически, не правда ли? В основном это означает только изменение данных, которые мы сохранили. Если бы мы хотели изменить значение имени человека с Джона на Марк, мы бы «изменили данные».

В этом состоит ключевое отличие между React и Vue. В то время как Vue по сути создает объект данных, где данные можно свободно обновлять, React создает объект состояния, где для обновления нужно немного больше работать..

Теперь React реализует дополнительную работу с полным основанием, и мы рассмотрим это чуть позже. Но сначала давайте посмотрим на данные объект с Vue и государство объект с React:

sZzmUCmi9Frf20OgPlXeFxeYutk5nVpYLyIo
pMzlry1q9FfWOoMj6TnLJoRBmfobAzf3MIuE
Объект данных Vue слева. Объект состояния реагирования направо.

Итак, вы можете увидеть, что мы передали одинаковые данные в оба, но они просто сказываются по-разному. Поэтому передача исходных данных в наши компоненты очень похожа. Но, как мы уже упоминали, то, как мы собираемся изменить эти данные, отличается между фреймворками.

Скажем, у нас есть элемент данных под названием name: ‘Sunil’.

В Vue мы ссылаемся на это, вызывая this.name. Мы также можем обновить это, позвонив по телефону this.name = ‘John’. Это изменило бы мое имя Джону. Я не уверен, что чувствую, когда меня зовут Джоном, но все бывает! ?

В React мы бы ссылались на ту же часть данных, вызывая this.state.name. Ключевое отличие здесь состоит в том, что мы не можем просто писать this.state.name = ‘John’, потому что React имеет ограничения, чтобы предотвратить такое легкое, беззаботное создание мутаций. Поэтому в React мы бы написали что-то вроде this.setState({name: ‘John’}).

Хотя это, в сущности, делает то же самое, что мы достигли в Vue, есть дополнительная часть записи, поскольку Vue по сути объединяет свою собственную версию setState по умолчанию всякий раз, когда часть данных обновляется.

Итак, коротко, React требует setState, а затем обновленных данных внутри него, тогда как Vue делает предположение, что вы хотели бы это сделать, если бы вы обновляли значение внутри объекта данных.

Почему React вообще беспокоится об этом, и почему setState вообще нужен? Давайте передадим это Реванту Кумару для объяснения:

«Это потому, что React хочет повторно запустить определенные хуки жизненного цикла, [such as] componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate, render, componentDidUpdate, когда состояние меняется. Он будет знать, что состояние изменилось, когда вы вызываете функцию setState. Если вы напрямую мутировали состояние, React пришлось бы выполнить гораздо больше работы, чтобы отслеживать изменения и какие крючки жизненного цикла запускать и т.д. Потому, чтоб сделать его обычным, React употребляет setState».

BjPx0SKGGAUNqBoLjDJRUwtctgPimca0DtjG
Бин знал лучше всего

Теперь, когда у нас нет мутаций, давайте перейдем к тонкостям, взглянув на то, как мы будем добавлять новые элементы в обе наши программы To Do.

Как мы создаем новые задачи?

Отреагировать:

createNewToDoItem = () => {
    this.setState( ({ list, todo }) => ({
      list: [
          ...list,
        {
          todo
        }
      ],
      todo: ''
    })
  );
};

Как React сделал это?

В React наше поле ввода имеет атрибут под названием значение. Это значение автоматически обновляется благодаря использованию нескольких объединяемых функций, чтобы создать что-то, что очень напоминает двухсторонняя привязка (Если вы никогда не слышали об этом раньше, есть более подробное объяснение в Как Vue это сделал раздел после этого). Мы создаем эту форму двустороннего связывания, имея дополнительную прослушиватель событий onChange прикреплен к введение поле.

Давайте быстро посмотрим на введение поле, чтобы вы могли увидеть, что происходит:

<input type="text" 
       value={this.state.todo} 
       onChange={this.handleInput}/>

Функция handleInput запускается при каждом изменении значения поля ввода. Он обновляет сделать который находится внутри объекта состояния, установив для него то, что находится в поле ввода. Эта функция выглядит так:

handleInput = e => {
  this.setState({
    todo: e.target.value
  });
};

Теперь, когда пользователь нажимает кнопку + кнопку на странице, чтобы добавить новый элемент, createNewToDoItem функция по существу запускает this.setState и передает ему функцию.

Эта функция принимает два параметра, первый – это целое list массив из объекта состояния, второй – это todo (который обновляется с помощью handleInput функция). Затем функция возвращает новый объект, содержащий все list от предыдущего, а затем добавляет todo в конце его. Весь список добавляется с помощью оператора распространения (Google это если вы не видели этого раньше — это синтаксис ES6).

Наконец-то мы поставили todo к пустой строке, которая автоматически обновляет значение внутри введение поле.

Vue:

createNewToDoItem() {
    this.list.push(
        {
            'todo': this.todo
        }
    );
    this.todo = '';
}

Как Vue сделал это?

В Vue наш введение поле имеет дескриптор под названием v-модель. Это позволяет нам делать что-то известное как двухсторонняя привязка. Давайте просто быстро посмотрим на наше поле ввода, а затем объясним, что происходит:

<input type="text" v-model="todo"/>

V-Model увязывает ввод этого поля с ключом, который мы имеем в нашем объекте данных под названием toDoItem. Когда страница загружается, мы имеем toDoItem установить пустую строку, как таковую: todo: ‘’. Если бы там уже были некоторые данные, например todo: ‘add some text here’наше поле ввода будет загружено из добавьте сюда текст уже внутри поля ввода.

В любом случае, возвращаясь к пустой строке, любой текст, который мы вводим в поле ввода, привязывается к значению для todo. Это фактически двусторонняя привязка (поле ввода может обновлять объект данных, а объект может обновлять поле ввода).

Так что оглядываясь на createNewToDoItem() блок кода из предыдущего, мы видим, что мы нажимаем содержимое todo в list массив а затем обновить todo к пустой строке.

Как удалить из списка?

Отреагировать:

deleteItem = indexToDelete => {
    this.setState(({ list }) => ({
      list: list.filter((toDo, index) => index !== indexToDelete)
    }));
};

Как React сделал это?

Итак, в то время как функция deleteItem расположена внутри ToDo.jsя очень легко мог сделать ссылку на это внутри ToDoItem.js сначала передав deleteItem() функционировать как опора <ToDoItem/> как таковой:

<ToDoItem deleteItem={this.deleteItem.bind(this, key)}/>

Это передает функцию вниз, чтобы сделать ее доступной для ребенка. Вы увидите, что мы также обязываем this а также передачу ключевого параметра, поскольку ключ – это то, что функция собирается использовать, чтобы различать какой ToDoItem мы стараемся удалить при нажатии. Затем внутри ToDoItem компонент, мы делаем следующее:

<div className=”ToDoItem-Delete” onClick={this.props.deleteItem}>-</div>

Все, что мне нужно было сделать, чтобы ссылаться на функцию, находящуюся внутри родительского компонента, это ссылка this.props.deleteItem.

Vue:

onDeleteItem(todo){
  this.list = this.list.filter(item => item !== todo);
}

Как Vue сделал это?

У Vue нужен немного другой подход. По сути, здесь мы должны сделать три вещи:

Во-первых, для элемента, который мы хотим вызвать функцию:

<div class=”ToDoItem-Delete” @click=”deleteItem(todo)”>-</div>

Затем мы должны создать функцию emit как метод внутри дочернего компонента (в этом случае, ToDoItem.vue), который выглядит так:

deleteItem(todo) {
    this.$emit('delete', todo)
}

Наряду с этим, вы заметите, что мы действительно ссылаемся на a функция когда мы добавляем ToDoItem.vue внутри ToDo.vue:

<ToDoItem v-for="todo in list" 
          :todo="todo" 
          @delete="onDeleteItem" // <-- this :)
          :key="todo.id" />

Это то, что известно как а пользовательский прослушивающий события. Он прослушивает любой случай, когда излучение запускается с помощью строки ‘delete’. Если он слышит это, он запускает вызванную функцию onDeleteItem. Эта функция находится внутри ToDo.vue, а не ToDoItem.vue. Как мы обсуждали ранее, он просто фильтрует todo массив внутри в data объект чтобы удалить элемент, на который было нажато.

Здесь также следует отметить, что в примере Vue я мог бы просто написать файл $emit часть внутри @click слушатель как таковой:

<div class=”ToDoItem-Delete” @click=”$emit(‘delete’, todo)”>-</div>

Это снизило бы количество шагов вниз с 3 до 2, и это просто зависит от личных предпочтений.

Кратко, дочерние компоненты в React будут иметь доступ к родительским функциям через this.props (при условии, что вы передаете реквизиты вниз, что является достаточно стандартной практикой, вы встретите это много раз в других примерах React). У Vue, с другой стороны, вы должны выдавать события от ребенка, которые обычно собираются внутри родительского компонента.

Как мы передаем слушателей?

Отреагировать:

Прослушивание событий для простых вещей, таких как события кликов, просты. Вот пример того, как мы создали событие клика для кнопки, создающей новый элемент ToDo:

<div className=”ToDo-Add” onClick={this.createNewToDoItem}>+</div>.

Здесь очень просто, и почти так, как мы бы обрабатывали встроенные onClick с ванильным JS. Как упоминалось в разделе Vue, настроить прослушиватель событий для обработки всякий раз, когда нажималась кнопка ввода, потребовалось чуть больше времени. Это, по сути, требовало onKeyPress событие, которое будет обрабатывать входной тэг, как:

<input type=”text” onKeyPress={this.handleKeyPress}/>.

Эта функция, в сущности, вызывала createNewToDoItem функция каждый раз, когда она распознает, что была нажата клавиша «enter», как таковая:

handleKeyPress = (e) => {
  if (e.key === ‘Enter’) {
    this.createNewToDoItem();
  }
};

Vue:

У Vue это очень просто. Мы просто используем @ символ, а затем тип обработчика событий, которые мы хотим сделать. Например, чтобы добавить прослушиватель события клика, мы можем написать следующее:

<div class=”ToDo-Add” @click=”createNewToDoItem()”>+</div>

Примечание: @click на самом деле это сокращение для письма v-on:click. Прекрасная вещь с прослушиванием событий Vue заключается в том, что есть также куча вещей, которые вы можете привязать к ним, например .once, что предотвращает запуск прослушивателя событий несколько раз. Существует также куча ярлыков, когда дело доходит до написания конкретных обработчиков событий для обработки нажатий клавиш.

Я обнаружил, что создание прослушивателя событий в React для создания новых элементов ToDo каждый раз, когда нажималась кнопка ввода, заняло немного больше времени. В Vue я смог просто написать:

<input type=”text” v-on:keyup.enter=”createNewToDoItem”/>

Как мы передаем данные дочернему компоненту?

Отреагировать:

В React мы передаем props дочернему компоненту в месте его создания. Как вот:

<ToDoItem key={key} item={todo} />

Здесь мы видим две опоры, переданные в ToDoItem компонент. С этого момента мы можем ссылаться на них в дочернем компоненте через this.props. Итак, чтобы получить доступ к item.todo prop, мы просто называем this.props.item.

Vue:

В Vue мы передаем props дочернему компоненту в месте его создания. Как вот:

<ToDoItem v-for="todo in list" 
            :todo="todo"
            :key="todo.id"
            @delete="onDeleteItem" />

Когда это будет сделано, мы передаем их в массив props в дочернем компоненте, как таковой: props: [ ‘todo’ ]. Затем на них можно ссылаться в ребенке за их именем – поэтому в нашем случае, ‘todo.

Как мы передаем данные обратно к родительскому компоненту?

Отреагировать:

Сначала мы передаем функцию дочернему компоненту, ссылаясь на нее как на сопротивление в том месте, где мы вызываем дочерний компонент. Затем мы добавляем вызов функции к ребенку любым способом, например onClickпутем ссылки this.props.whateverTheFunctionIsCalled. Тогда это запустит функцию, находящуюся в родительском компоненте.

Мы можем увидеть пример всего этого процесса в разделе «Как удалить из списка».

Vue:

В нашем дочернем компоненте мы просто пишем функцию, возвращающую значение родительской функции. В нашем родительском компоненте мы пишем функцию, которая прослушивает, когда выделяется это значение, которое затем может вызвать вызов функции. Мы можем увидеть пример всего этого процесса в разделе «Как удалить из списка».

И вот у нас! ?

Мы рассмотрели, как мы добавляем, удаляем и изменяем данные, передаем данные в форме реквизитов от родителей к дочернему и посылаем данные от ребенка к родительскому в виде прослушивателей событий.

Конечно, между React и Vue есть много других небольших отличий и прихотей, но, надеюсь, содержание этой статьи помог послужить основой для понимания того, как обе фреймворки обрабатывают вещи?

Если вы нашли это полезно, поделитесь им в социальных сетях и прокомментируйте!

Vue ToDo: https://github.com/sunil-sandhu/vue-todo

React ToDo: https://github.com/sunil-sandhu/react-todo

Это синдицированный репост для freeCodeCamp в сотрудничестве с Javascript In Plain English. Оригинальную версию этой статьи можно найти здесь.

Добавить комментарий

Ваш адрес email не будет опубликован.