Разверните полнофункциональное полнофункциональное приложение с нуля. Часть 3 из 4.

В этом руководстве мы подключим GraphQL API к независимому интерфейсу Vue.js.

Вступление

Vue.js - это прогрессивный JavaScript-фреймворк, позволяющий любому, кто знает HTML, CSS и JavaScript, быстро запустить приложение.

Говорят, что Vue.js взял лучшее от Angular и React, а затем улучшил их, создав Vue.js. Лично я считаю, что Vue.js действительно интуитивно понятен как для внутренних, так и для интерфейсных разработчиков.

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

Предпосылки

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

Знания HTML и CSS - это хорошо, но мы не будем вдаваться в подробности - мы сосредоточимся больше на частях JavaScript и Vue.js. Обязательно ознакомьтесь с синтаксисом шаблонов Vue.js.

Чтобы продолжить, вам нужно будет выполнить Часть 2 этой серии или клонировать репозиторий из Git. Я настоятельно рекомендую хотя бы бегло просмотреть часть 2, чтобы получить общее представление о том, с какими данными мы работаем.

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

git clone https://github.com/siegfriedgrimbeek/fastify-graphql-api.git
cd fastify-graphql-api
npm i

Не стесняйтесь переименовать папку во что-нибудь более интуитивно понятное.

Первое, что мы хотим сделать, это разделить файлы нашего проекта на внутреннюю (сервер) и внешнюю (клиентскую).

Для этого в каталоге проекта root создайте два каталога, а именно каталог aserver и каталог aclient. Как только они будут созданы, скопируйте весь существующий код в папку server.

Прежде чем мы инициализируем интерфейс Vue.js в каталоге client, нам нужно дать нашему клиенту разрешение на взаимодействие с сервером, что можно сделать, включив совместное использование ресурсов между источниками (CORS).

Включение совместного использования ресурсов между источниками (CORS)

Совместное использование ресурсов между источниками (CORS) - это механизм, который использует дополнительные заголовки HTTP, чтобы сообщить браузеру, что веб-приложение, работающее в одном источнике (домене), имеет разрешение на доступ к выбранным ресурсам с сервера в другом источнике. Веб-приложение выполняет HTTP-запрос с несколькими источниками, когда запрашивает ресурс, источник которого отличается от источника (домен, протокол или порт).

В каталоге server установите пакет fastify-cors npm с помощью следующей команды:

npm i fastify-cors

После завершения установки пакета добавьте следующие файлы в server.js файл в папке src:

...
// Enable the fastify CORS plugin
fastify.register(require('fastify-cors'), {
   origin: '*',
   credentials: true
})
...

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

В целях тестирования убедитесь, что у вас запущен экземпляр серверного приложения, что можно сделать, перейдя в каталог server и запустив приложение:

npm run start

Теперь в другом окне терминала перейдите в каталог client. Теперь мы начнем с Vue.js.

Инициализировать и настроить новый проект Vue.js

Мы будем использовать инструмент Vue CLI для создания проекта. В каталоге client запустите следующее:

npm install -g @vue/cli

Это установит инструмент Vue CLI как глобальный пакет npm. Обратите внимание, что вам могут потребоваться разрешения для установки пакета, поэтому обязательно выполните команду с sudo для Mac и от имени администратора для Windows.

После завершения установки выполните следующую команду:

vue create .

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

Выберите установку приложения в каталог c urrent, а затем выберите вариант выбора функций вручную и выберите следующее:

  • Вавилон
  • Маршрутизатор
  • Vuex
  • Препроцессоры CSS
  • При желании выберите Linter / Formatter

Не выбирайте режим истории для маршрутизатора, а выберите Sass / SCSS (с node-sass) в качестве препроцессора CSS.

Если вы выбрали вариант Linter / Formatter, не стесняйтесь настраивать его в соответствии с вашими потребностями в разработке.

Наконец, выберите вариант сохранения настроек в специальном файле конфигурации и сохраните настройки как предустановку с именем fastify-app. Это позволит вам использовать его снова на более позднем этапе.

Ваше приложение Vue.js теперь устанавливается. Как только это будет сделано, установите следующие дополнительные пакеты NPM:

npm i apollo-boost bootstrap-vue vue-apollo vue-moment graphql

Аполлон-буст

Apollo Boost - это способ без каких-либо настроек начать использовать Apollo Client. Он включает некоторые разумные значения по умолчанию, такие как наши рекомендуемые InMemoryCache и HttpLink, которые настроены для вас с нашими рекомендуемыми настройками.

Apollo Client - это полнофункциональный кэширующий клиент GraphQL с интеграцией для React, Angular и других. Он позволяет легко создавать компоненты пользовательского интерфейса, которые извлекают данные через GraphQL. Чтобы получить максимальную отдачу от apollo-client, вы должны использовать его с одной из интеграций уровня представления.

Vue-apollo

Интегрируйте GraphQL в свои приложения Vue.js!

Boot-strap-vue

С BootstrapVue вы можете создавать в Интернете адаптивные, ориентированные на мобильные устройства проекты, используя Vue.js и самую популярную в мире интерфейсную библиотеку CSS - Bootstrap v4.

Вью-момент

Удобные фильтры Moment.js для вашего проекта Vue.js. Анализируйте, проверяйте, изменяйте и отображайте дату и время в JavaScript.

Пришло время проверить здравомыслие. Запустим приложение:

npm run serve

Теперь ваше приложение должно работать на http: // localhost: 8080 /.

Обзор приложения

Все файлы для разработки приложений находятся в каталоге src, который создается в каталоге dist внутри каталога src. Структура следующая:

В каталоге views есть три основных представления:

  • Home.vue
  • Car.vue *
  • Owner.vue *

* Вы можете создать эти файлы в каталоге views.

В каталогеcomponents есть три повторно используемых компонента:

  • Header.vue *
  • CarCard.vue *
  • EditCar.vue *

* Вы можете создать эти файлы в каталоге components.

У нас также есть некоторые вспомогательные файлы, используемые для файлов маршрутизации (router.js), управления состоянием (store.js) и настройки (main.js), которые уже были созданы с помощью инструмента Vue CLI.

Напишем код

Первое, что мы хотим сделать, это перейти к папке src и обновить файл main.js следующим кодом:

В приведенном выше коде мы импортируем несколько зависимостей, инициализируем библиотеки, создаем Apollo client и p rovider и создаем экземпляр Vue.

Вышеупомянутые ссылки относятся к общей документации Apollo, но применимы ко всем фреймворкам. Документация по Vue Apollo доступна здесь.

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

Затем мы добавляем в файл router.js следующий код:

Выше мы просто импортируем внешние зависимости и файлы представления. Затем инициализируем роутер и настраиваем маршруты.

Объекты маршрутов состоят из пути, имени, компонента (представления) и того, передаются ли ему какие-либо реквизиты.

Реквизиты передаются со следующим синтаксисом:

:id

Vue Router - официальный маршрутизатор для Vue.js. Он глубоко интегрирован с ядром Vue.js, что упрощает создание одностраничных приложений с Vue.js.

Узнайте больше о маршрутизации и Vue Router здесь.

Давайте обновим файл store.js следующим кодом:

В приведенном выше коде мы импортируем внешние зависимости и инициализируем Vuex. Затем мы настраиваем хранилище Vuex, в котором указываем начальное состояние приложения, а также ожидаемые мутации.

Vuex - это шаблон + библиотека управления состоянием для приложений Vue.js. Он служит централизованным хранилищем для всех компонентов в приложении с правилами, гарантирующими, что состояние может изменяться только предсказуемым образом. Он также интегрируется с официальным расширением инструментов разработчика Vue для предоставления расширенных функций, таких как отладка с нулевой конфигурацией во времени и экспорт / импорт снимков состояния.

Вот отличная статья, посвященная более глубокому изучению Vuex.

Теперь давайте обновим файл theApp.vue, заменив следующий код:

Vue Router загрузит тот же Home.vue, что и страница по умолчанию, потому что мы указали домашний вид по умолчанию (/) route.

Мы загружаем router-view в наше приложение с помощью следующего кода:

<router-view />

Затем мы объявляем и запускаем CarsQuery, который вернет все автомобили в базе данных, а затем зафиксирует результат в хранилище Vuex.

Обратите внимание, что CarsQuery выполняется перед монтированием компонента с использованием beforeMount() ловушки жизненного цикла.

Не стесняйтесь регистрировать переменную response в консоли или использовать расширение Vue dev-tools, чтобы увидеть ответ в нашем магазине Vuex.

Создание представлений и компонентов

Во-первых, мы можем добавить приведенный ниже код в компонент Header.vue:

С помощью приведенного выше кода мы создаем простой компонент Header многократного использования со строковыми реквизитами title и intro. Компонент заголовка построен с использованием Bootstrap Jumbotron Component.

Затем мы можем заполнить компонент CarCard.vue:

Здесь мы используем Компонент Bootstrap Card с объектом Car в качестве опоры. Детали автомобиля и его свойства отображаются с использованием синтаксиса шаблона Vue, и у него есть два события щелчка, которые используют Vue Router для перехода к индивидуальному представлению Car или к представлению Owner, которое мы реализуем дальше.

Мы используем Lorem Flickr API для обслуживания изображений, связанных с автомобилем, используя следующий код:

:img-src="`https://loremflickr.com/350/200/${car.brand},${car.title}`"

Нам нужно указать URL-адрес API, ширину изображения и высоту изображения. Затем мы используем литералы шаблона, чтобы указать марку автомобиля и название автомобиля, которые берутся из объекта car.

Два события щелчка, viewCar(id) и viewOwner(id), используют Vue Router для перехода к своим соответствующим страницам, но прежде чем они сработают, мы должны сначала заполнить эти представления.

Наконец, есть некоторые правила стилей CSS, в которые мы не будем вдаваться.

Теперь, когда у нас есть два компонента, которые будут использоваться Home.vue, мы можем обновить Home.vue следующим образом:

В приведенном выше коде мы используем два компонента, которые мы создали ранее.

Для компонента Header мы привязываем следующие реквизиты:

v-bind:title="'My Car Garage'"
v-bind:intro="'A MongoDB, fastify and GraphQL powered Vue.Js app'"

Для компонента CarCard мы перебираем массив carData (полученный из хранилища Vuex), используя функцию отрисовки списка. Здесь мы привязываем объект car как опору и предоставляем car.id в качестве ключа.

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

В теге скрипта мы импортируем зависимости и компоненты. Затем мы используем помощник mapState, чтобы сгенерировать для нас вычисленную функцию получения, загружая carData в состояние. Подробнее о помощнике mapState здесь.

Санитарная проверка

Если все прошло хорошо, мы должны увидеть загруженные автомобили на главной странице:

Как указано выше, события @click работают, поскольку они перенаправляют на правильные представления, но на данный момент эти представления пусты, поэтому давайте заполним их.

Просмотр автомобиля

В каталоге views и в файле Car.vue добавьте следующий код:

Давайте разберем каждую часть по частям, начиная с тега <template>.

Как и в случае с другими нашими представлениями и компонентами, мы используем синтаксис шаблона Vue для визуализации деталей автомобиля. Это создает макет, состоящий из заголовка, хлебных крошек, сведений об автомобиле, призыва к действиям и компонента EditCar.

Мы перебираем массив services в объекте car.services, перечисляя все услуги или отображая сообщение, когда в автомобиле нет услуг.

В цикле обслуживания мы используем библиотеку moment.js для форматирования даты.

{{ service.date | moment("DD/MM/YYYY") }}

В блоке btn-container мы перечисляем наш призыв к действиям с соответствующими функциями.

Наконец, мы используем Bootstrap modal для формы Edit Car, которая запускается кнопкой Edit.

В теге <script> мы импортируем зависимости и компоненты и объявляем два запроса, а именно запросы getCar и deleteCar, которые используются для получения данных об одном автомобиле и их удаления.

Затем мы объявляем наши исходные данные компонентов, свойства, вычисленные данные, компоненты и методы.

В beforeMount() ловушке жизненного цикла мы запускаем функцию getCarDetails(), передавая id в качестве переменной, которая возвращает все данные отдельного автомобиля, а затем фиксирует результат в хранилище Vuex.

Функция goHome() вернет на одну страницу назад в истории.

Функция deleteCar() изменит наши данные, удалив автомобиль с id, который мы передали в качестве переменной, а затем зафиксирует результат в хранилище Vuex.

EditCar

В теге <template> мы создаем форму и привязываем каждый ввод формы к соответствующему значению с помощью директивы v-model.

Мы привязываем кнопку ОК к событию onSubmit с помощью следующего кода:

@ok="onSubmit"

В теге <script> мы импортируем зависимости и объявляем запрос editCar, который используется для редактирования данных отдельного автомобиля.

Затем мы объявляем данные и свойства наших исходных компонентов.

Наконец, мы объявляем метод onSubmit(evt), который использует запрос editCar для обновления автомобиля, передавая данные формы ({ …data }) в качестве новых данных автомобиля, которые затем сохраняются в хранилище Vuex. Затем модальное окно скрывается.

Просмотр владельца

К настоящему времени вы должны уловить шаблон в коде, поскольку большая часть кода в представлении Owner уже обсуждалась в предыдущих компонентах и ​​представлениях.

Мы повторно используем компонент Header и компонент CarCard - только на этот раз отображаем все автомобили, принадлежащие конкретному владельцу.

Заключение

Я действительно надеюсь, что это руководство служит двойной цели - продемонстрировать простоту извлечения данных и манипулирования ими с помощью GraphQL, а также простоту кодирования и интуитивно понятный характер Vue.js.

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

Что дальше?

Единственное, что нам осталось сделать, - это развернуть. Это может показаться простым, но у нас есть пара свободных концов, которые нужно связать, чтобы по-настоящему объединить все воедино.

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

Как обычно, весь код из вышеприведенного руководства доступен на GitHub.