Пейзаж JavaScript стремительно развивается. И это мягко говоря.

Но среди вихря новых фреймворков и библиотек есть несколько потрясающих инструментов.

Какие из них вам следует использовать? Ну, несколько. Сейчас мне больше всего нравится Vue.js.

Этот прогрессивный фреймворк JavaScript стоит вашего времени (клянусь, честь скаута).

Будь то рефакторинг интерфейса вашего приложения, создание сложного SEO-ориентированного SPA или запуск простого блога.

И создание блога Vue.js - это именно то, на чем я собираюсь сегодня сосредоточиться.

В этом посте я собираюсь предоставить демонстрацию и обложку блога Vue.js с открытым исходным кодом:

  • Настройка и маршрутизация
  • Отображение ленты вашего блога с помощью фильтров
  • Отображение отдельных сообщений с комментариями
  • Создание настраиваемого плагина Vue для разделения ваших данных

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

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

Разделение проблем в нашем приложении для блога Vue

Взгляните на важные части дерева документа:

Я не буду вдаваться в подробности настройки веб-пакета. Но те, кто знаком с Vue, узнают vue-cli шаблон веб-пакета. Мы также используем vue-router для маршрутизации.

Я добавил только две папки в базовую настройку: src/sass и src/resources. В другой раз мы выясним, почему Sass приложения Vue отделен от компонентов.

В папку src/resources мы поместим наш разделенный уровень доступа к данным, который мы обсудим в конце сообщения.

В самом дереве компонентов нет ничего революционного:

  • <Blog> - Наша домашняя страница
  • <BlogNav> - обрабатывает логику навигации
  • <BlogFeed> - Отображает список сообщений
  • <BlogPost> - отображает отдельную запись
  • <BlogFooter> - отображает статический нижний колонтитул

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

Я использовал несколько нетрадиционный подход, так как маршрутизатор всегда отображает один и тот же компонент. Мы сами занимаемся отображением нужного контента, компонент <Blog> - это наш главный концентратор, отправляющий реквизиты своим трем дочерним элементам.

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

Второй - наш фильтр авторов, доступ к которому осуществляется путем перехода к /by/:author. Vue-Router захватывает все узлы пути, которым предшествует :, как переменные и вставляет их значение в компонент маршрута как свойства.

И последнее, но не менее важное: мы делаем то же самое для маршрута /read/:post, который будет отображать содержимое одного сообщения в блоге.

Отображение ленты блога

А пока мы пропустим фактическое получение данных и предположим, что они уже загружены. Вот как выглядит <BlogFeed> Компонент:

Как вы можете видеть в верхней части скрипта, мы получаем объект filters от родительского компонента <Blog>. Вычисляемое свойство feed() позаботится об обработке любых изменений фильтров по мере их появления. Он фильтрует массив сообщений, перебирая каждый активный фильтр и выполняя соответствующую функцию для сообщения. Затем он возвращает только сообщения, прошедшие все тесты.

В нашем шаблоне мы v-for отфильтрованный канал, который будет постоянно обновлять его. Вероятно, это наиболее эффективный способ работы с фильтрами. Поскольку вы можете легко добавлять новые, добавляя новый метод в filterBy.

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

Если вы склонны, я недавно рассказывал о некоторых используемых здесь переходах Vue на CSS-трюках.

Отображение отдельных сообщений в блоге

Хорошо, у нас есть правое изображение, отображаемое с левой стороны. Теперь нам нужно только внести соответствующий контент справа от него. Это может показаться нелогичным, но компонент <BlogPost> всегда ждет, чтобы что-то сделать.

Как только маршрут /read/:post будет достигнут, он загрузит соответствующий пост и отобразится в поле зрения с помощью Vue <transition>. Остальное - это простой старый шаблон Vue, в котором указаны правильные переменные. Обычно вы получаете тело сообщения с предварительно вставленным HTML. Обязательно используйте атрибут v-html вместо {{ mustaches }}, чтобы избежать автоматического экранирования тегов.

В демо я использовал Disqus вместе с vue-disqus для добавления комментариев к сообщениям. Это то, что мне больше всего нравится в состоянии фронтенд-разработки в наши дни. Вы можете добавить такие функции за считанные минуты.

Разделение данных Vue: слово в JAMstack

JAMstack (JavaScript, API и разметка) - это продукт быстрого развития веб-интерфейса в последние годы, особенно в сообществе JS.

Разберитесь в стеке JAM с помощью этого ключевого разговора.

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

  • Легкость доступа. Знакомые языки / фреймворки в сочетании с абстрактными внутренними интерфейсами затрудняют сопротивление. Я не был бы шокирован, узнав, что большинство интерфейсных разработчиков разделяют мою боязнь баз данных.
  • Разделенный источник данных Теоретически не имеет значения, откуда поступают ваши данные или сколько API вы вызываете для их получения, если вы можете передать их в свое приложение. Для веб-сайтов это означает, что вы никогда не будете строго привязаны к своей CMS. При необходимости вы можете поменять местами.

Почему это имеет значение?

Мне нравится работать с данными, но я не люблю ими управлять.

Несвязанный бэкэнд - без сомнения, привлекательная перспектива. Тот, который я продал своему боссу, когда собирался создать веб-сайт с Vue.js и безголовой CMS. Как оказалось, очень легко позволить структуре данных вашего API определять внутреннюю работу вашего приложения. Рано или поздно вы обнаружите, что задаетесь вопросом, что же случилось со всем аргументом о «несвязанности».

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

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

Создание подключаемого модуля ресурса

Эта демонстрация блога представляет собой простой пример с открытым исходным кодом, показывающий, как вы могли бы это сделать, не добавляя никаких зависимостей, кроме lodash.merge (4,2 КБ в сжатом виде).

Часто самый простой способ с Vue - использовать его систему плагинов. Вероятно, вы уже использовали это раньше, например, при установке маршрутизатора или Vuex. Напоминаю, что все, что вам нужно сделать, это передать плагин Vue.use() вместе с любыми параметрами перед созданием корневого экземпляра Vue.

За кулисами Vue берет объект плагина и ищет install()method. Он вызывает этот метод, передавая Vue в качестве первого аргумента, а объект параметров - в качестве второго.

В этой области вы можете сделать множество приятных вещей. Но наша миссия сегодня - только создать $getResource метод экземпляра. Вы сможете вызвать этот метод с помощью this.$getResource(method, options) из компонента. Этот подход довольно крутой, поскольку он монтируется к каждому новому экземпляру компонента. Это причудливый способ сказать, что вы получаете доступ к this привязке компонента, как вы привыкли.

Перейдите на ./resources/resource.js:

Мы назначаем метод $getResource прототипу Vue. Как видите, у нас есть варианты endpoint и resources.

  • endpoint - это объект resources и базового URL API, к которому мы будем добавлять пути наших запросов.
  • resources - это «реализации» или определения, указывающие, как обращаться с ресурсом.

Мы очень скоро займемся этим.

Метод install() создает замыкание, фиксируя эти параметры в своей области действия. Любая определенная здесь функция всегда будет иметь к ним доступ.

Перейдя к функции, после нескольких проверок, чтобы убедиться, что у нас все есть, мы вызываем метод resource. Этот метод определен для принятия строки в качестве первого аргумента и передачи любой опции, полученной в качестве второго аргумента. Мы берем свойство path и метод resolve и определяем три наших преобразователя:

  • pipe() возвращает данные в обещании
  • merge() использует утилиту слияния lodash для глубокого слияния dataSet с $data компонента
  • set() перебирает клавиши dataSet, назначая их $data

Этот последний бит - довольно хороший способ добавить ярлык без запутывания кода. Оба метода сохраняют реактивность Vue и возвращают обещание. Затем мы можем связать .then(dataSet => {}), чтобы запустить некоторую логику после завершения выборки.

Наконец, вызывается собственный метод fetch() ES2015. Ответ JSON анализируется и передается вместе с сопоставителями функции resolve.

Реализации ресурсов

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

Откройте implementation/BlogPost.js:

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

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

Соединение точек

Теперь мы можем начать работу, сказав Vue использовать наш настраиваемый плагин. Сначала мы создаем индекс в нашей папке реализаций. Этот индекс объявляет export { default as ResourceName } from './ResourceName' для каждого ресурса.

В main.js мы передаем плагин и нашу коллекцию ресурсов во Vue следующим образом:

Вызов ваших ресурсов

Теперь все, что осталось сделать, - это вызвать ресурсы из наших компонентов, добавив параметр resource с именем ресурса, который мы хотим использовать. Когда мы вызываем this.$getResource, он будет знать, какой из них загрузить. Я включил некоторые образцы данных JSON в каталог static/api, который будет загружен и обработан нашим плагином.

Возьмем, например, <BlogPost>:

Все просто. У нас есть схема объекта данных нашего компонента, заполненная заполнителями, как рекомендовано Vue и нашим определением ресурса. В хуке beforeMount() мы проверяем, попал ли посетитель прямо на маршрут сообщения в блоге, и вызываем его. В противном случае мы ждем изменения свойства post и реагируем загрузкой нового сообщения.

Нам даже не нужно назначать ответ данным. Он назначается нашим компонентным данным резолверами. Лично мне такой подход очень нравится, потому что:

  1. Мне нравятся вещи, которые облегчают мою жизнь.
  2. Мне нравится, когда другие люди могут понять, что происходит. Наши данные-заполнители четко определены, и вызовы $getResource намекают, что мы получаем данные.

Потрясающие! Мы избегаем любых ссылок, относящихся к реализации нашего API внутри компонента. Вместо этого мы вызываем наши методы AJAX, используя идентификатор. Как и в случае с Vuex, официальным плагином Vue для управления состоянием.

Результат: живая демонстрация блога Vue.js (укради!)

Посмотреть / украсть демонстрацию на GitHub

Посмотреть живую демонстрацию, развернутую на Netlify от GH

Заключительные мысли

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

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

Не адаптируйте свое приложение к данным, а адаптируйте данные к своему приложению.

Хотя вышеизложенное является данностью для многих back-end разработчиков, это может быть новой территорией для front-end разработчиков.

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

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

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

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

Изначально я опубликовал это в Блоге Snipcart и поделился им в нашем информационном бюллетене.