Добро пожаловать в новую серию, в которой мы создадим полноценную платформу для ведения блогов с Vue.js и Storybook, основанную на блокчейне Steem!
Узнайте, как использовать Storybook.js для Vue и как создавать независимые приложения с использованием шаблона компонент / контейнер. Исходный код этой части доступен здесь. Следующая часть серии Создание поста доступна здесь.
В этой серии будут представлены все лучшие практики, шаблоны и инструменты, которым я научился при создании крупных приложений с использованием Vue.js, TDD и других основных инструментов за последние два года.
Во введении мы:
- Настройте приложение Vue
- Настройте Storybook.js для Vue
- Получение данных из блокчейна Steem с помощью
steem.js
- Отображение данных с использованием шаблона контейнера / компонента
- Создайте
<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.
В следующей статье мы немного улучшим пользовательский интерфейс и покажем подписчикам, а также начнем настраивать аутентификацию.
Спасибо за прочтение. Любые комментарии или вопросы приветствуются, и, опять же, источник этой части доступен здесь.