Vue.js - это библиотека javascript для создания приложений, управляемых данными, в соответствии с шаблоном / архитектурой MVVM (Model-View-ViewModel). Vue легкий, быстрый и простой в освоении, но, как и сам javascript, он гибкий и обманчиво мощный с точки зрения возможностей, которые он дает нам как разработчикам для создания реактивных, основанных на компонентах веб-приложений, управляемых данными, которые выгодно отличаются от приложений, разработанных с использованием более популярных библиотек / такие фреймворки, как React, Angular или Ember. Экземпляр приложения Vue.js построен вокруг «виртуальной машины» в архитектуре MVVM.

Код для всех приложений, упомянутых в этой серии, доступен на github. Инициалы M, V и VM будут использоваться в этой статье для обозначения Model, View и ViewModel соответственно.

ОБЗОР:

В этой серии статей мы рассмотрим ключевые особенности Vue.js и вспомогательные библиотеки, такие как vue-resource и vue-router, которые позволяют нам создавать 3 основных типа приложений.

  1. Базовая виртуальная машина, многокомпонентные приложения: у этого типа приложений не будет возможностей AJAX или маршрутизации. например простое приложение TODO на основе браузера.
  2. Базовая виртуальная машина, многокомпонентные приложения с возможностями AJAX: это тип приложения, который мы имеем в виду, когда говорим, что приложение «управляется данными». Это приложение будет запрашивать хранилище данных для извлечения данных, которые оно будет отображать в браузере, например. простое приложение для управления клиентами для малого бизнеса.
  3. Базовая виртуальная машина, многокомпонентные приложения с AJAX и маршрутизацией на стороне клиента: это типичный SPA. Этот вид приложений использует большинство функций экосистемы Vue.js, и это приложение, которое мы создадим для предприятия, стартапа или бизнеса для поддержки внутреннего или клиентского программного обеспечения. например приложение для управления заказами с социальной аутентификацией через OAUTH.

Давайте начнем.

ОСНОВЫ:

Vue.js, как упоминалось ранее, построен на принципе MVVM, поэтому 3 основных компонента приложения Vue - это виртуальная машина, V и M.

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

M - это просто объект Javascript, который содержит то, что мы можем назвать «рабочим набором данных», который требуется виртуальной машине для питания V и реакции на действия пользователя.

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

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

Код для этого примера следующий:

Первый раздел, который мы рассмотрим, - это M. Строки 28–31 уведомления, эти разделы кода определяют M для Vue VM, мы замечаем, что это простой объект javascript, содержащий 2 свойства «title» и «user». Затем мы исследуем виртуальную машину в строках 32–35. Первое, что мы замечаем, это то, что виртуальная машина является «экземпляром» конструктора «Vue». В этом тривиальном примере мы просто определяем 2 свойства для объекта параметров, передаваемого виртуальной машине «el» и «data».

‘El’ ссылается на элемент HTML, который будет привязан к виртуальной машине и будет служить ее V, ‘data’ ссылается на объект javascript, который будет привязан к виртуальной машине и будет служить ее M.

В этом примере «el» привязан к «div» с «id» из «app», а «data» привязан к объекту с идентификатором «model». NB мы могли бы просто определить эту встроенную строку следующим образом:

var app = new Vue({
  el: '#app',
  data: {
    title: ‘Sample Vue app’,
    user: ‘’
  }
});

Теперь давайте рассмотрим V. Строки 20–24 - это интересные для нас части. Обратите внимание на строку 20 - «div» имеет идентификатор «app». Это, безусловно, самая важная часть V - это идентификатор, который должен быть уникальным и соответствовать любому значению, которое имеет свойство «el» объекта параметров виртуальной машины.

В строке 21 мы встречаем нашу первую привязку данных, простую «интерполяцию», при которой мы динамически предоставляем значение для вставки в HTML. Обратите внимание, что это значение является значением свойства «title» M виртуальной машины (строка 29).

В строке 22 мы встречаем нашу первую директиву, мы «двусторонне привязываем» значение виджета «input» к значению свойства «user» M виртуальной машины (строка 30). Эта «двусторонняя привязка» гарантирует, что все, что мы вводим во «input», будет установлено как значение для свойства «user».

В строке 23 мы видим результат применения «двусторонней привязки». Мы интерполируем значение свойства «пользователь» M виртуальной машины в HTML-код. Поскольку это значение ранее было «двусторонним» с использованием «v-модели», все, что пользователь вводит в виджет «input», будет отображаться динамически!

Из этого тривиального примера мы узнаем, что привязки данных и директивы в V ДОЛЖНЫ быть свойствами объекта параметров виртуальной машины. Сюда входят «методы» обработки пользовательского ввода, самым основным из которых является «v-модель».

Теперь, когда у нас есть базовое понимание динамики приложения Vue, давайте перейдем к чему-то более практическому (в конце концов, это практическое руководство).

BASE VM, МНОГОКОМПОНЕНТНЫЕ ПРИЛОЖЕНИЯ:

Этот тип приложений возникает довольно часто, мы используем их для множества простых задач - внутренних и клиентских. Хороший пример - приложение TODO. Как «нетривиальное» приложение, оно будет использовать одну из самых мощных функций Vue - компоненты.

Это то, что мы будем строить, можете играть ручкой.

Структура каталога:

/
| - package.json
| - index.html
| - main.js
| - components
       | - allTodos
              | - index.js
              | - template.html
       | - completedTodo
              | - index.js
              | - template.html
       | - newTodo
              | - index.js
              | - template.html
       | - uncompletedTodo
              | - index.js
              | - template.html

package.json:

БАЗОВАЯ ВМ:

Давайте начнем изучение возможностей Vue.js с изучения базовой виртуальной машины. В этом примере базовая виртуальная машина будет использовать структуру HTML, как определено в index.html как V. Обратите внимание, что упоминаемый скрипт не app.js, а main.js, потому что мы при разработке этого приложения используют watchify как «средство сборки / сборки модулей».

Index.html:

Строки 22–33 - это интересные для нас части структуры HTML. В строке 22 мы помечаем элемент HTML, который будет служить «точкой монтирования» для базовой виртуальной машины, то есть «el» базовой виртуальной машины. Это «div» с «id =» app »». В строке 23 мы сталкиваемся с мощной функцией Vue.js - настраиваемым элементом, который определяет компонент. Компоненты Vue.js разработаны в соответствии со стандартом «Веб-компоненты» и позволяют нам определять пользовательские элементы HTML, которые представляют повторно используемые структуры HTML в нашем коде (подробнее об этом скоро).

Просто изучив название компонента, мы поймем, что он представляет - новые задачи!

Строки 25–30 охватывают группу кнопок, которые представляют различные действия, которые пользователи могут выполнять в самом приложении Todo. Эти действия становятся возможными с помощью директив, например ‘@ click.stop.prevent =” viewAllTodos ”‘, которые позволяют базовой виртуальной машине перехватывать действия пользователя и действовать в соответствии с ними на основе обработчиков, на которые ссылаются директивы. Обратите внимание, что в данном случае @ является сокращенным обозначением v-on, .stop и . prevent '- это' модификаторы ', которые изменяют поведение события.

Директиву можно интерпретировать следующим образом: «при возникновении события щелчка на этом элементе выполните следующие действия: 1)« остановите »распространение события, т.е. модификатор« .stop », 2)« предотвратите »поведение события по умолчанию, т.е. '.prevent' - в этом случае не уходите со страницы и 3) вызовите обработчик (т.е. метод) 'viewAllTodos' базовой виртуальной машины.

NB. Предыдущее объяснение справедливо для любого V виртуальной машины Vue.js независимо от того, является ли эта виртуальная машина «базовой виртуальной машиной» или компонентом (подробнее об этом скоро).

В строке 32 мы встречаем специальный элемент Vue.js - элемент «component». Назначение этого элемента - позволить «родительской» виртуальной машине динамически отображать «дочерние виртуальные машины», то есть компоненты, которые используют одну и ту же точку монтирования. Это позволяет переключать разные «экраны» без подробного кодирования. «Компонент» имеет 3 атрибута, которые действительно важно понимать.

  1. ‘: is’ - эта специальная привязка атрибута отвечает за определение того, какой компонент должен быть динамически отображен. Обратите внимание на полный атрибут ‘: is =” activeComponent ”. Это означает, что «родительский» компонент или базовая виртуальная машина должны иметь свойство данных «activeComponent», которое представляет «дочерний компонент», который будет динамически отображаться каким-либо действием. Выбор «activeComponent» в качестве имени является произвольным, вы можете дать ему любое имя по своему усмотрению. Для полноты картины я должен указать, что в недавнем взаимодействии с Эван Ю (автор Vue.js) он указал мне, что «компонент» также может использоваться для рендеринга список компонентов виртуальной машины. Но более обычная практика - это то, что я описал здесь. Для полноты, ': is' является сокращением для 'v-bind: is', что означает, что атрибут 'is' базовой виртуальной машины привязан к определенному свойству данных на той же виртуальной машине (в этом case 'activeComponent') обратите внимание, что 'is' просто указывает, какой 'компонент' должен быть отрисован в этой точке монтирования. Это динамическое связывание, которое позволяет дочерним компонентам динамически отображаться в одной и той же точке монтирования.
  2. ’keep-alive’ - чтобы избежать постоянного повторного рендеринга при отключении динамических компонентов, мы используем атрибут «keep-alive» для кэширования отключенного компонента в памяти. Это означает, что состояние компонента на момент выключения сохраняется. Это действительно полезно.
  3. ’: todos-list’ - Vue.js и другие реактивные библиотеки, например В React есть концепция «свойств» - тезисы представляют собой механизмы, которые позволяют «родительскому» компоненту / виртуальной машине передавать данные от себя к зависимому «дочернему элементу 'компонент. В этом случае полный атрибут prop - ‘: todos-list =” todos ”‘. Поскольку эта опора определена в теге 'components', мы можем интерпретировать намерение этого кода следующим образом: опора 'todos-list' любого дочернего компонента, который динамически отображается через эту точку монтирования, получает свое значение из 'todos' свойство данных базовой ВМ. Обратите внимание, что "prop" определяется здесь в "kebab-case", то есть в "todos-list", но в компоненте, который будет использовать эту опору, он ДОЛЖЕН быть определенным в "camelCase", например «TodosList» (подробнее об этом скоро).

Таким образом, эти три атрибута дают нам мощные возможности в определении поведения и возможностей наших динамически визуализируемых компонентов.

App.js.

app.js содержит код базовой виртуальной машины. Поскольку мы используем «watchify» в качестве инструмента сборки / сборщика модулей для разработки, мы можем разработать эту часть нашего приложения с помощью операторов «require ()» в стиле CommonJS. В строке 5 нам требуется наша единственная зависимость модуля - vue. Строки 12–75 содержат тело базовой виртуальной машины, которая отвечает за связывание всех компонентов этого приложения вместе.

В строке 12 мы создаем экземпляр базовой виртуальной машины и передаем объект «options» конструктору Vue. Давайте исследуем составляющие свойства этого объекта и поймем, как они влияют на общее поведение приложения.

В строке 13 мы определяем свойство «el», которое служит точкой монтирования для виртуальной машины, через которую будет отображаться буква V. В строках 14–17 мы определяем свойство «модель данных», которое определяет M, из которого виртуальная машина извлекает свой «рабочий набор данных». Строка 15 определяет свойство «todos» как массив, напомним, что это свойство «todos» предоставляет значение для свойства «todos-list» динамически отображаемых компонентов, которые совместно используют точку монтирования «component».

Строка 16 определяет свойство «activeComponent», которое, как мы заметили, имеет значение «по умолчанию» app-uncompleted-todo. Если мы вспомним объяснение того, как работает ': is', мы поймем, что намерение здесь может быть выражено следующим образом: «Когда базовая виртуальная машина изначально визуализируется, дочерний компонент, который должен быть установлен в ' Точка монтирования компонента должна быть компонентом, который соответствует компоненту app-uncompleted-todo ».

Обратите внимание, что, хотя мы определили выделенную точку монтирования для компонента ‘app-new-todo’ (index.html строка 23), другие компоненты, которые должны быть динамически обработаны, просто совместно используют точку монтирования ‘component’. Если вы изучите это приложение с помощью инструментов chrome dev, вы увидите, что отображается не «app-new-todo» или «компоненты», а фактический HTML, на который ссылается компонент (подробнее об этом скоро).

В дальнейшем значение по умолчанию для свойства activeComponent базовой виртуальной машины (которое определяет, что дочерний компонент будет динамически визуализироваться) будет «app-uncompleted-todo».

Строки 18–41 определяют «методы» базовой виртуальной машины, эти методы по сути являются обработчиками событий DOM, которые реагируют на различные события, запускаемые действием пользователя на V и перехватываемые директивами, например, ‘@click’, ‘methods’ также могут быть просто методами, то есть функциями объекта, которые могут быть вызваны для выполнения определенных задач.

Строки 19–30 определяют обработчики событий DOM, которые обрабатывают события «щелчка» на V, как определено в index.html (строки 25–30). Взяв в качестве примера первый из них (строки 19–22), мы замечаем, что метод просто «устанавливает» для свойства «activeComponent» базовой виртуальной машины новое значение, например

this.activeComponent = ‘app-all-todos’;

который устанавливает «activeComponent» в «app-all-todos» и, таким образом, вызывает рендеринг компонента, на который ссылается «app-all-todos», в точке монтирования «component».

Строки 31–40 определяют «метод», который предоставляет некоторые услуги базовой виртуальной машине, мы вскоре рассмотрим это подробно. Строки 42–47 определяют «компоненты» базовой виртуальной машины. Каждый компонент по сути является экземпляром расширения конструктора Vue.js.

Компоненты обычно создаются следующим образом:

var component = Vue.extend({…options…});

Однако в этом случае с помощью «watchify» мы можем разбить наше приложение на модули, определив каждый компонент в отдельном модуле, а затем «потребовав» этот компонент. Каждый компонент, как определено в строках 43–46, соответствует настраиваемому тегу, например. мы видим, как тег «‹app-new-todo›» (index.html строка 23) ссылается на компонент, определенный в строке 43. Другие компоненты (строки 44–46) динамически отображаются и совместно используют точку монтирования «компонента» (index.html, строка 32), как объяснялось ранее. Вскоре мы подробно рассмотрим каждый компонент.

Следующим «разделом» базового объекта параметров виртуальной машины является свойство «events». Это свойство определяет обработчики настраиваемых событий, которые отвечают за обмен данными между базовой виртуальной машиной и ее дочерними компонентами.

Давайте рассмотрим пару таких обработчиков пользовательских событий. Строка 49 определяет событие «newtodo». Когда это событие генерируется, вызывается обработчик и передается «todo» в качестве аргумента, в строке 51 обработчик вставляет новое «todo» в массив «todos» базовой виртуальной машины, а затем обработчик выполняет две интересные вещи: 1 ) 'транслирует' событие 'getnewtodo' вместе с задачей, переданной ему в качестве аргумента (строка 52), 'широковещательная передача' - это механизм Vue.js, позволяющий родительской виртуальной машине / компоненту связываться с 'дочерними' компонентами и обеспечивать конкретное действие выполняется без непосредственного изменения родительским состоянием дочернего состояния. Это очень круто, поскольку позволяет использовать слабосвязанные компоненты. Заинтересованные компоненты, которые подписаны на событие «getnewtodo», будут обрабатывать их, когда это событие будет сгенерировано. 2) «транслирует» другое событие «updatetodos» (строка 53), которое будет обрабатываться компонентами, подписанными на это событие.

Строка 55 объявляет событие и обработчик «completedtodo». Обратите внимание, как в строке 57 обработчик вызывает метод extractTodo, ранее определенный в строках 31–40, а возвращаемое значение используется в строке 58 для изменения значения «завершено» для задачи, переданной обработчику в качестве аргумент. Поведение остальных обработчиков можно легко определить, следуя той мысли, которую мы только что использовали.

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

APP-NEW-TODO:

Этот компонент находится в каталоге components / newTodo. Мы замечаем, что он состоит из двух файлов / модулей - index.js и template.html. Эван Ю предпочитает отдельные файловые компоненты, т.е. шаблон и сценарий содержатся в одном файле. Я предпочитаю отделить скрипт от разметки, поскольку разметка или скрипт могут быть довольно длинными, и я думаю, что их будет проще разделить. Так что мы примем мои предпочтения :-).

Начнем с изучения буквы V в соответствии с определением в "template.html".

Сначала вспомним, что точка монтирования для этого компонента определена в строке 23 файла index.html, т.е. «‹app-new-todo› ‹/app-new-todo›», однако фактическая структура компонента содержится в файле template.html 'находится на рассмотрении.

HTML, который будет использоваться для рендеринга этого компонента, по сути, представляет собой форму с виджетом ввода и виджетами с двумя кнопками. Виджет ввода - это «двусторонняя привязка данных» к свойству «todo» компонентной виртуальной машины (строка 5), в то время как кнопки привязаны к методам «addTodo» и «discardTodo» компонентных строк 10 и 14 виртуальной машины.

Продолжая, давайте рассмотрим код компонента, содержащийся в ‘index.js’.

NB. Вы можете вспомнить, что использование index.js в качестве точки входа по умолчанию для модуля, представленного каталогом, является распространенной идиомой в мире Node.js.

В строке 2 index.js мы начинаем с объявления свойства «template» и установки для него значения «require (‘ ./ template.html ’)». Давайте обсудим здесь 2 вещи.

  1. Когда компонент объявлен в Vue.js, можно использовать «el» или «шаблон» для ссылки на элемент HTML, который будет служить точкой монтирования для этого компонента. Если используется «el», то необходимо установить значение «el» как функцию, возвращающую элемент HTML. Если используется «шаблон», наша цель состоит в том, чтобы содержимое разметки ссылочного шаблона (либо в виде строки, либо в обязательном порядке, как мы сделали здесь) заменило точку монтирования этого компонента. По этой причине ‘‹app-new-todo› ‹/app-new-todo› не отображается в инструментах разработчика. Короче говоря, проще и удобнее использовать «шаблон» для ссылки на элемент DOM, через который будет отображаться буква V компонента.
  2. Использование require (‘./ template.html’) »позволяет нам использовать созданную нами разметку в отдельном файле благодаря функции« partialify ». Я думаю, это действительно удобно. Двигаемся дальше.

Строки 3–7 определяют свойство «данные» этого компонента. Обратите внимание, что в отличие от базовой виртуальной машины (строки 14-17 файла app.js) значение этого свойства - это функция, которая возвращает объект, а не POJO (простой старый объект javascript). Почему? Вспомните, что в javascript значения объектов передаются по ссылке, т.е. новый объект не создается, поэтому, если компонент используется в нескольких частях приложения, любое изменение его состояния повлияет на другие копии этого компонента. Однако, если объект, возвращаемый функцией, используется в качестве свойства данных, то каждая «копия» объекта данных является уникальным экземпляром, и изменения его свойств не влияют на другие копии этого компонента.

Хорошо, обратите внимание, что для свойства «todo» (строка 5) изначально задана пустая строка, это уместно, потому что мы предполагаем, что значение этого свойства будет определяться пользовательским вводом. Вот почему мы «двусторонне привязали» это свойство «todo» к виджету ввода в шаблоне (строка 5 файла «template.html»).

Строки 9–19 определяют метод addTodo.

Давайте рассмотрим этот метод. После подтверждения того, что событие щелчка на кнопке (строка 10 файла template.html) происходит, когда пользователь что-то ввел во входной виджет (строка 10 index.js), мы создаем новый объект для представления 'todo' (строки 11–14), затем мы очищаем виджет ввода, устанавливая свойство 'todo', к которому он привязан, с пустой строкой (строка 15), а затем генерируется событие 'newtodo' с новым 'todo' объект, который мы создали как данные (строка 16).

Подобно тому, как мы обнаружили, что «this. $ Broadcast» - это механизм, с помощью которого родительская виртуальная машина взаимодействует с дочерними компонентами, аналогично «this. $ Dispatch» - это то, как дочерние компоненты взаимодействуют с родительской виртуальной машиной. Опять же, это отличный пример слабой связи.

Мы делаем это, потому что базовая виртуальная машина является фактическим «владельцем» задач, которые создаются этим приложением Todo, мы хотим гарантировать, что всякий раз, когда что-то должно быть сделано с «задачей», единственным компонентом нашего приложения, который может действовать на основе того, что «todo» - это базовая виртуальная машина, и поэтому мы видим причину появления строк 49–54 файла app.js.

В строках 25–28 компонент обрабатывает событие «changetodo», мы можем догадаться, что он делает, исследуя строку 27, в которой значение свойства «todo» установлено равным значению свойства «todo» элемента «todo». 'объект получен как данные для события' changetodo '.

Изучив компонент app-new-todo, перейдем к изучению компонента app-uncompleted-todo.

ПРИЛОЖЕНИЕ-НЕЗАВЕРШЕННОЕ-ТОДО:

Как обычно, этот компонент состоит из двух файлов: index.js и template.html. Начнем с изучения ‘template.html’.

В строке 3 мы отмечаем, что элемент «p» имеет директиву «v-show», которая привязана к свойству «noTodos» компонента. Изучив этот элемент, мы можем правильно предположить, что цель состоит в том, чтобы отобразить только сообщение «Нет задач для отображения!» сообщение, если нет (незавершенных) задач для отображения.

Строки 4-17 - самые интересные для нас части, Vue.js делает почти тривиальным отрисовку списка, полученного из массива или объекта. Мы встречаем директивы, отвечающие за такое поведение, в строке 5, то есть v-for = "todo in todos". Эта директива «говорит» для каждого «todo» (или любого другого имени, которое мы выбираем для этого) в свойстве «todos» компонента визуализировать / создавать следующие элементы HTML (строки 6–15).

Строка 6 представляет собой интерполяцию, которая вставляет значение свойства todo элемента «todo» из массива «todos» в разметку. Строки 8–13 представляют собой группу кнопок, которые позволяют нам выполнять действия с отображаемым «делом». Как мы уже знаем, каждая директива, то есть «@ click.stop.prevent», ссылается на метод компонента. Затем давайте рассмотрим код компонента, содержащийся в index.js.

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

В Vue.js хуки жизненного цикла позволяют нам использовать события, запускаемые на определенных этапах цикла «создание / уничтожение» виртуальной машины Vue, и реализовывать определенную логику в этих точках. Для наших целей мы ответим на «скомпилированное» событие. Наше намерение состоит в том, чтобы запустить определенный код непосредственно перед тем, как виртуальная машина будет вставлена ​​в DOM, в этот момент времени (то есть, когда запускается 'скомпилированное' событие) все директивы были связаны со свойствами данных базового экземпляра виртуальной машины, поэтому любые изменения в состоянии вызовет обновления DOM.

Взяв его сверху, мы встречаем ожидаемое присвоение свойству ‘template’ значения, указывающего на файл ‘template.html’. Следующие строки 5 и 6 содержат определения массива «todos» и свойства «noTodos». Из строк 3 и 5 файла «template.html» мы знаем, что эти свойства данных определяют, отображать ли «Нет задач для отображения!» и разрешить шаблону отображать «список» незавершенных «задач» соответственно.

В строке 9 мы встречаем свойство «props», и, как и ожидалось, идентификатор находится в «camelCase»; как мы можем вспомнить, значение атрибута «todosList» предоставляется этому компоненту из базовой виртуальной машины, то есть в строке 32 файла «index.html». Есть 3 метода, которые реагируют на события щелчка на V (строки 11–22), и они просто запускают пользовательские события, которые «отправляются» на базовую виртуальную машину вместе с необходимыми данными, например настраиваемое событие «completedtodo» вместе с объектом «todo», который необходимо пометить как завершенный. Вспомните, что использование этих настраиваемых событий позволяет нам создать слабосвязанное приложение из составляющих его компонентов.

Строки 24–42 содержат свойство «события», поскольку, как мы можем вспомнить, это настраиваемые события, запускаемые родительской виртуальной машиной (в данном случае базовой виртуальной машиной), обработчики которой назначаются на этот компонент. Два пользовательских события, которые этот компонент прослушивает и на которые реагирует, - это события getnewtodo и updatetodos.

Когда запускается 'getnewtodo', обработчик принимает объект 'todo' в качестве аргумента, он подтверждает, что 'todo' действительно является 'незавершенным' todo, запрашивая свойство '.completed' объекта 'todo' (строка 26) , затем он устанавливает для свойства noTodos значение false (строка 28), гарантируя, что сообщение больше не отображается, и просто вставляет новое «todo» в начальный индекс массива «todos» (строка 29).

Когда запускается updatetodos, обработчик сначала очищает свой массив «todos» (строка 34), а затем фильтрует объект props «todosList» для всех незавершенных «todos». Вспомните, поскольку свойство '' todosList '' само связано с массивом 'todos' базовой ВМ (строки 32 index.html и строка 15 app.js), любые изменения в массиве 'todos' базовой ВМ будут автоматически отражены в объекте «todosList», а это означает, что все «задачи» будут присутствовать независимо от степени их выполнения.

NB для полноты картины позвольте мне указать, что мы могли бы использовать фильтр, чтобы список todos действовал как опора для «app-uncompleted-todo 'компонентом будут только те, у которых есть только незавершенный статус, однако я считаю, что, поскольку более чем одному компоненту требуется доступ к массиву задач базовой виртуальной машины по разным причинам, более элегантно сделать одно назначение пропуска и обработать фильтрацию в компоненте уровень.

В дальнейшем, после очистки текущего массива «todos», обработчик фильтрует объект prop «todosList» только для тех «todos», которые не завершены, то есть строки 35-37, а затем присваивает значение отфильтрованного массива (строка 39) для массив todos, а затем он делает что-то интересное - обратите внимание, что он возвращает true в строке 40.

В Vue.js, когда настраиваемое событие «транслируется» от родительской виртуальной машины к дочерним компонентам, первый компонент, реагирующий на событие, предотвращает распространение события, если обработчик не возвращает «истина», это означает, что в этом случае поскольку мы хотим, чтобы несколько дочерних компонентов реагировали на одно и то же событие updatetodos (как мы вскоре увидим), обработчики каждого компонента ДОЛЖНЫ возвращать значение true.

Строки 43–52 знакомят с «скомпилированным» обработчиком крючка жизненного цикла. Намерение здесь заключается в том, что до того, как компонент будет вставлен в DOM, проверьте, есть ли какие-либо незавершенные 'todos' в объекте 'todosList' (строка 45), если нет, затем отобразите сообщение no todos (строка 46 и строка 3 файла template.html). ), иначе не отображать сообщение (строка 49) и запускать событие updatetodos на самом себе (строка 50). NB в Vue.js, когда нам нужна виртуальная машина для запуска события на самой себе, используется синтаксис «this. $ Emit (‘ eventname ’, optionalData);». На этом мы завершаем рассмотрение компонента app-uncompleted-todo.

ПРИЛОЖЕНИЕ-ЗАВЕРШЕНО-ЗАДАЧИ:

По названию компонента мы можем правильно предположить его функцию - отображать все «задачи», которые пользователь выполнил. Как обычно, он находится в собственном каталоге, состоящем из двух файлов - index.js и template.html. Начнем с изучения template .html.

Мы замечаем сообщение no todos в строке 3 и связанную с ним директиву v-show. Мы также отмечаем, что «тело» HTML - это просто отображение списка завершенных задач, в частности строк 5 и 7.

Переходим к index.js.

Мы замечаем ожидаемые свойства шаблона и данных (строки 2–8). Мы также видим, что этот компонент также реагирует на запуск события updatetodos (строки 11–26), но на этот раз вместо фильтрации незавершенных «задач» он фильтрует завершенные единицы (строки 13–17) перед возвратом 'true' (строка 25), чтобы событие могло продолжить распространение.

Обработчик «скомпилированного» события жизненного цикла работает аналогично компоненту «app-uncompleted-todo». На этом мы завершили рассмотрение этого компонента и переходим к последнему компоненту, app-all-todos.

ПРИЛОЖЕНИЕ-ВСЕ-ЗАДАЧИ:

Этот компонент очень похож на ранее рассмотренный, то есть «app-completed-todos», template.html просто отображает «список» задач, содержащихся в массиве «todos» компонентной виртуальной машины.

Аналогичным образом структура index.js очень похожа на структуру компонента app-completed-todos.

Единственное существенное различие заключается в способе обработки события 'updatetodos': вместо фильтрации завершенных или незавершенных задач обработчик просто очищает исходные данные, содержащиеся в массиве 'todos', а затем повторно заполняет массив значением объекта prop 'todosList' (строки 12–14 файла index.js).

Итак, мы рассмотрели базовую виртуальную машину и компонентные виртуальные машины этого простого приложения Todo, созданного с помощью Vue.js.

ПОВТОР.

Давайте резюмируем основные моменты, затронутые в этой статье.

  1. Vue.js позволяет нам создавать веб-приложения, управляемые данными, с помощью реактивного метода на основе компонентов.
  2. Приложение Vue.js следует архитектуре / шаблону MVVM.
  3. Базовый экземпляр Vue - это виртуальная машина, с которой связаны компоненты V и M. Компонент V определяется структурой HTML, к которой привязана виртуальная машина, путем ссылки на «id» элемента HTML. M виртуальной машины предоставляет виртуальной машине свой «рабочий набор данных» и представляет собой просто литерал объекта javascript или объект, возвращаемый функцией (для компонентов).
  4. Все экземпляры Vue VM состоят из следующих свойств: el / template, data, computed, methods, events и перехватчики жизненного цикла.
  5. V виртуальной машины Vue привязан к своей виртуальной машине с помощью директив и привязок данных - это отношение, которое позволяет V быть реактивным и управлять данными.
  6. Для достижения наилучших результатов любое нетривиальное приложение Vue.js должно быть создано из базовой виртуальной машины и любого количества компонентов.
  7. Две ключевые конструкции, которые связывают компонент с его родительской виртуальной машиной, - это «свойства» и «события»; эти две конструкции позволяют слабо связывать компонентное веб-приложение.
  8. Существует 3 основных подхода к созданию веб-приложений на основе компонентов в Vue.js: использование пользовательских тегов сценария в разметке / использование строк, определение компонента в одном файле и отделение разметки компонента от кода (как мы использовали в этом пример).

В следующей статье этой серии мы рассмотрим, как создать веб-приложение с поддержкой AJAX, используя Vue.js. Благодарим за прочтение. Как обычно, свяжитесь с нами, если у вас есть вопросы или комментарии ниже.