Добро пожаловать в новую серию, в которой мы создадим полноценную платформу для ведения блогов с Vue.js и Storybook, основанную на блокчейне Steem!

Узнайте, как использовать Storybook.js для Vue и как создавать независимые приложения с использованием шаблона компонент / контейнер. Исходный код этой части доступен здесь. Следующая часть серии Создание поста доступна здесь.

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

Во введении мы:

  1. Настройте приложение Vue
  2. Настройте Storybook.js для Vue
  3. Получение данных из блокчейна Steem с помощью steem.js
  4. Отображение данных с использованием шаблона контейнера / компонента
  5. Создайте <Profile> компонент в сборнике рассказов

Почему сборник рассказов? Что такое шаблон контейнера / компонента?

Storybook помогает еще больше отделить презентационные компоненты (те, которые ориентированы только на отображение вещей) и компоненты-контейнеры, которые обрабатывают вызовы API, манипулируют и хранят локальное состояние и т. Д.

Storybook позволяет дизайнерам и разработчикам работать вместе более эффективно, не мешая друг другу. Разработчики проводят большую часть своего времени, работая над бизнес-логикой, вызовами API и в магазинах Vuex, а дизайнеры, как правило, сосредотачиваются на CSS, макетах и ​​том, как все выглядит и течет.

Это также делает ваше приложение более тестируемым - тесты презентационных компонентов обычно подтверждают правильность свойств и правильность разметки. Компоненты контейнера больше связаны с вызовом функций, взаимодействием с внешними службами и манипулированием данными, передаваемыми в компонент представления. Дан Абрамов хорошо объясняет это здесь.

Что такое Steem?

Steem - это платформа вознаграждений на основе блокчейна, позволяющая издателям монетизировать контент и развивать сообщество.

По сути, это распределенная социальная сеть, построенная на технологии блокчейн. Существует несколько веб-клиентов, например steemit.com. Вы также можете следить за мной там.

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

Начиная

Мы загрузим приложение, используя vue-cli. Если вы его еще не установили, запустите yarn global add vue-cli. Теперь создайте приложение с vue init webpack vue-steem. Я буду создавать полноценное приложение с маршрутизацией, юнит-тестами [jest] и e2e-тестами. Если вы хотите следовать инструкциям, ответьте «да» на все запросы при запуске vue init.

(Необязательно) Установите vue-component-scaffold

Я написал небольшой инструментальный модуль npm для создания шаблонов компонентов Vue и сопутствующий тест под названием vue-component-scaffold. Вы можете прочитать об этом здесь, если вас интересует установка с npm install -g vue-component-scaffold. Я буду использовать во время этой серии.

Установите steem.js

Просто запустите yarn install steem — save. Steem - социальная сеть на базе блокчейна. Мы будем использовать API для обслуживания профилей, публикаций, голосований и получения вознаграждений. Самый распространенный интерфейс для доступа к контенту - steemit.com.

Создайте начальный маршрут профиля и компоненты

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

mkdir src/views
mkdir src/views/profile
vc src/views/profile/Index -t
vc src/views/profile/Profile -t

vc - это команда для vue-component-scaffold. Если вы не хотите его использовать, просто создайте пустые .vue файлы с тем же именем и следуйте инструкциям.

Внутри views/profile/Index.vue добавьте:

Теперь отредактируйте src/router/index.js и используйте вновь созданный маршрут.

Запустите yarn dev, чтобы запустить сервер разработки. Если вы ввели все правильно и я не сделал ошибок, localhost:8080/#/profile должен показать вам белую страницу с профилем !!! нравится:

Хорошо выглядеть.

Установили steem.js раньше. Давайте воспользуемся этим, чтобы получить некоторые данные, а затем добавим сборник рассказов и начнем видеть контейнер / компонент в действии.

Сначала внутри /views/profile/ProfileContainer.vue был создан метод mounted, в котором мы сделаем вызов API и получим некоторые данные о пользователе. Также нам нужно будет импортировать модуль steem.

Если вы обновите страницу, вы должны увидеть данные, напечатанные на консоли с множеством полей. Мы будем работать с этими данными. На данный момент нас интересует поле json_metadata, которое содержит имя учетной записи, местоположение, биографию и изображение профиля. Покажем! Но сначала сделайте шаг назад и подумайте, как лучше всего это сделать?

Теперь у нас есть два компонента для работы: Profile.vue и ProfileContainer.vue. Последний в настоящее время выполняет вызов API. Другой способ взглянуть на это ProfileContainer.vue - это умный компонент или то, что часто называют компонентом контейнером. Он извлекает и обрабатывает данные. Profile.vue будет тем, что часто называют презентационным компонентом - он будет отображать некоторые данные, но не должен знать, откуда эти данные или их содержимое.

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

Установите и настройте Storybook.js

Установите сборник рассказов, запустив yarn add @storybook/vue —-save. Затем внутри package.json добавьте:

{
  “scripts”: {
    “storybook”: “start-storybook -p 9001 -c .storybook”
  }
}

Это сценарий запуска сборника рассказов. Теперь нам нужно создать каталог .storybook на том же уровне, что и src. Внутри добавьте config.js со следующим:

Затем снова внутри .storybook создайте webpack.config.js. Нам нужно немного расширить конфигурацию веб-пакета по умолчанию (эта настройка может потребовать некоторой работы, но оно того стоит)!

В приведенном выше config.js (а не в webpack.config.js, приведенном выше) мы сделалиrequire ..src/stories, которого не существует. Создайте каталог src/stories, а внутри создайте index.js и profile.js. index.js просто импортирует историю для Profile.vue, которую мы собираемся создать!

index.js просто содержит:

import profile from ‘./profile’

profile.js содержит рассказ:

Если вы напечатали / скопировали все это правильно, run yarn storybook -c и посетите localhost:9001, и вы должны увидеть:

Теперь мы можем приступить к работе. Обратите внимание, что в profile.js в свойстве template мы просто визуализируем <Profile />. Компонент Profile.vue не сможет выполнять вызовы API, отправлять действия или делать что-нибудь необычное. Изображение сборника рассказов в изолированной среде без подключения к Интернету. Пользовательский интерфейс не должен иметь ничего общего с внешними службами, API или бизнес-логикой. Просто визуализируйте данные из props. Таким образом, мы можем использовать сборник рассказов, чтобы проверить правильность пользовательского интерфейса, и модульные тесты, чтобы убедиться, что данные и реквизиты верны.

Мы хотим иметь возможность разрабатывать наши компоненты презентации, например Profile.vue, полностью отделенными от логики приложения. Начнем с этого. Внутри Profile.vue добавьте следующее:

Теперь Profile.vue знает, что он получит profileImage от props, который будет ссылкой на место, где хранится изображение пользователя. Внутри stories/profile.js обновите историю, включив в нее такое изображение:

Я знаю, что сказал, что сборник рассказов должен работать, не полагаясь на внешние службы! Вы, вероятно, думаете: «Эй, Vue.js - это внешний сервис…!», И, конечно, вы правы. Позже мы настроим некоторые статические изображения, сохраняемые локально. На данный момент это нормально, чтобы убедиться, что сборник рассказов и наша первая история настроены и работают правильно.

Предполагая, что у вас все еще работает сервер сборников рассказов, посетите localhost:9001. Вас должны встретить:

Большой! Фантастическая работа. Вы только что написали свою первую историю для полностью независимых компонентов пользовательского интерфейса. Давайте продолжим и напишем логику в ProfileContainer.vue, чтобы мы могли использовать изображение, возвращаемое из Steem API.

Сначала мы обновим ProfileContainer.vue, data и mounted.

Мы добавили result, чтобы сохранить ответ, и loaded. Мы не хотим отображать <Profile> до завершения вызова API. Мы записываем результат вызова API в result и устанавливаем loaded равным true, когда вызов API (надеюсь) завершается успешно.

Далее разметка:

Ничего особенного - просто передайте свойство profile_image result.profile. Теперь. посещение localhost:8080/#/profile

Отличная работа! Мы знали, что это сработает, так как видели это в stories/profile.js, но также приятно видеть это вживую.

Добавим остальные данные профиля. На этот раз я просто передам весь result.profile как prop. В будущем я хотел бы выделить аватар в отдельный компонент, который я мог бы использовать в других местах на веб-сайте, например, в списке подписчиков или рядом с моими сообщениями, поэтому я хочу выделить его отдельно от других данных. .

Нам нужно только обновить раздел <template> в ProfileContainer.vue:

А затем добавьте новую опору и разметку в Profile.vue:

localhost:8080/#/profile должен выглядеть так:

Не забудьте обновить stories/profile.js.

Красивый!

Теперь мы настроены для большого приложения - наш уровень данных в ProfileContainer.vue и уровень представления в Profile разделены. Мы также создали сборник рассказов. Приложение сейчас выглядит довольно некрасиво, но ничего страшного. Разработчики могут пойти дальше и добавить больше функций, а мы можем передать репозиторий дизайнерам, которые могут работать с пользовательским интерфейсом, даже не обращаясь к API. Вооружившись сборником рассказов, все, что нужно дизайнерам, это работать в Profile.vue , а разработчики сосредоточились на построении бизнес-логики в виде контейнеров.

Более того, дизайнеры могут даже пойти дальше и создать компоненты с помощью сборника рассказов, предполагая, что они знают, какие данные они могут ожидать получить. Возможно, дизайнер может начать создавать Post.vue компонент, который красиво форматирует сообщение в блоге. Свойства достаточно очевидны, и когда разработчики могут, они могут подключить его к PostContainer.vue и передать свойства Post.vue компоненту представления.

Последнее, что нужно сделать, это написать несколько модульных тестов. Мы хотим убедиться, что вызов API выполнен и результат назначен правильно. В это время loaded должен быть установлен на true и раскрывать <Profile> компонент. Я не буду этого делать, потому что в следующей части этой серии мы переместим вызов API в службу, которая, в свою очередь, вызывается путем отправки действия Vuex.

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

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