Моя клиентка недавно попросила создать для своего сайта простую галерею изображений, в которой будет отображаться ее лента в Instagram. Я подумал: Нет проблем, у Instagram наверняка простой API, и этот вариант использования, вероятно, их самый простой Hello World! пример." Однако просмотр «документации по API Instagram, в которой практически нет реальных примеров кода, только запутал воду. Идентификаторы клиентов, секреты клиентов, токены доступа? Все это казалось излишеством для отображения собственной общедоступной ленты Instagram человека. Гугл тоже мало помог - я нашел в основном ужасные сообщения о том, что Instagram закрывает доступ к общедоступному API (что верно, но необходимый нам доступ предполагается до 2020 года, итак: и далее!).

Однако я наткнулся на один пример приложения и увидел, что позвонить в Instagram проще простого:

let response = await fetch(   ‘https://api.instagram.com/v1/users/self/media/recent/?access_token=' + this.access_token )

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

Я надеюсь, что эта статья:

  • помогите всем, кто хочет создать простой показ своей ленты в Instagram
  • предоставить реальный пример Vue для начинающих Vue
  • ощутите простоту и мощь CSS Grid для создания макетов

Вот еще один пример того, что мы создаем: Мои Инстаграммы на моем веб-сайте.

Получение токена доступа

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

Настройка оболочки страницы

В моем случае галерея должна была располагаться на простой веб-странице, а не как часть веб-приложения. Это то, что мне действительно нравится в Vue: как и в случае с jQuery, вы можете просто перетащить его на свою страницу и использовать по мере необходимости. Это не должно менять способ создания вашего сайта или страницы. Наша галерея Instagram будет довольно автономной, если не считать двух внешних ресурсов Javascript и, конечно же, вызова API Instagram. Вот оболочка страницы:

Мы представляем разрабатываемую версию Vue.js, а также Axios.js, которая является предпочтительной библиотекой для выполнения HTTP-запросов из браузера во Vue. Вы можете использовать собственный fetch () API, или vue-resource, или что вам подходит. Если вы уже загружаете jQuery на страницу по другим причинам, вы даже можете использовать его функцию $ .ajax ().

Затем у нас есть места для наших стилей, немного HTML и вкус Javascript.

Код Vue

Давайте будем смелыми и сначала напишем наш Javascript:

Мы создаем новый экземпляр Vue и сначала сообщаем Vue, каким элементом управлять с помощью el: '#app'. Затем мы настроили некоторые данные для Vue, чтобы отслеживать:

data: {
  access_token: "your access token here",
  url: "https://api.instagram.com/v1/users/self/media/recent/",
  username: "",
  grams: [],
  next_url: "",
  error: false
},

Значения url и access_token не изменятся (вставьте токен доступа, который вы получили выше). Остальные будут обновлены позже в нашем коде. Еще у нас есть одно вычисляемое свойство:

computed: {
  instapage() {
    return 'https://www.instagram.com/' + this.username
  }
},

Значение instapage - это просто URL-адрес страницы пользователя в Instagram. Да, вы уже знаете, каким будет username для вашей собственной галереи, поэтому иметь это и instapage в качестве динамических свойств немного глупо, но это демонстрирует использование вычисленных свойств. А меньшее количество жестко запрограммированных значений делает код более универсальным и упрощает его повторное использование в будущих проектах.

Далее у нас есть сердце нашего маленького приложения, метод getGrams():

methods: {
  getGrams() {
    axios.get(this.url + "?access_token=" + this.access_token)
      .then(({data}) => {
        this.grams = data.data
        this.username = data.data[0].user.username
        this.next_url = data.pagination.next_url
      })
      .catch(function (error) {
        console.log(error)
        this.error = true
      });
  },
...
}

Мы используем Axios для вызова URL-адреса Instagram с добавленным нашим access_token. В случае успеха мы обновляем наши data свойства. Это существенный сдвиг в мышлении, который вы должны сделать между jQuery и Vue: с Vue все, о чем вы беспокоитесь, - это данные. Больше не нужно искать элементы, создавать элементы, добавлять элементы - код Javascript, который вы пишете, манипулирует и обновляет данные, на которых основано ваше приложение, и вы позволяете Vue работать с DOM.

(Примечание: несколько сбивчиво, Axios возвращает объект response со свойством data, а API Instagram также имеет свойство data, которое содержит массив наших сообщений Instagram. Отсюда и вложенные свойства data.)

Теперь нам нужно какое-то событие, чтобы вызвать вызов метода getGrams(). Те, кто знаком с jQuery, привыкли оборачивать код в $(document).ready() или один из его эквивалентов. В нашем случае мы хотим вызвать наш метод не, когда документ будет готов, а когда будет готов экземпляр Vue, и для этого мы можем использовать один из хуков жизненного цикла Vue:

created() {
  this.getGrams();
}

Итак, как только экземпляр был «создан» Vue (наблюдение за данными, вычисленные свойства, методы, обратные вызовы наблюдения / события, все были установлены), вызовите наш getGrams() метод, который извлекает наши данные из Instagram.

В нашем экземпляре Vue есть второй метод getMoreGrams(). Наряду с нашим массивом сообщений API Instagram возвращает next_url, который мы можем использовать для получения следующего пакета сообщений, таким образом:

getMoreGrams(){
  axios.get(this.next_url)
    .then(({data}) => {
      this.grams = this.grams.concat(data.data)
      this.next_url = data.pagination.next_url
    })
    .catch(function (error) {
      console.log(error)
      this.error = true
    });         
}

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

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

Тело приложения Vue

Далее мы напишем наш код шаблона HTML / Vue:

Здесь у нас есть один контейнерный div с идентификатором #app (который может удобно размещаться рядом с другими элементами HTML - вашей основной навигацией, нижним колонтитулом и т. Д.).

После простого заголовка с нашим именем пользователя мы хотим, чтобы divs, содержащий каждую ссылку и изображение, были прямыми дочерними элементами нашей сетки CSS. Для этого мы используем элемент template как невидимую оболочку. Мы можем разместить здесь наше v-if условное выражение, чтобы разметка внутри выводилась только в том случае, если у нас есть Instagrams для отображения:

<template v-if="grams.length > 0">

В этом случае мы перебираем каждый из них и выводим изображение, заключенное в ссылку, используя данные, полученные из Instagram:

<div v-for="(gram, index) in grams">
  <a :href="gram.link">
    <img :src="gram.images.standard_resolution.url" :alt="gram.text" />
  </a>
</div>

Пока нам нечего показывать, мы можем показать простую графику загрузчика:

<div v-else class="loading"></div>

И если звонок в Instagram не удастся, мы можем извиниться:

<div v-if="error" class="error">Sorry, the Instagrams couldn't be fetched.</div>

Наконец, если зрителю просто нравится наша работа и он не может насытиться, мы предоставляем кнопку для загрузки следующей «страницы» нашего канала:

<button @:click="getMoreGrams">Load More</button>

(@ - это сокращение от v-on.)

Макет с помощью CSS Grid

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

Сначала мы помещаем множество наших числовых значений в CSS custom properties на :root element (в нашем случае это htmlelement). Это удобно тремя способами:

  • Вы можете легко изменить тему галереи для других сайтов.
  • Вы можете легко поддерживать согласованность значений без препроцессора или многократного поиска / замены.
  • В инструментах разработчика все интересные свойства, с которыми можно поиграть, собраны в одном месте (элемент html), без необходимости переходить к объявлениям отдельных элементов:

Затем мы настраиваем нашу сетку на #app:

#app{
  display: grid;
  grid-gap: var(--spacing);
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  min-height: calc(100vh - var(--spacing)*2);
}

Мы задаем нашей сетке некоторый интервал и устанавливаем столбцы с минимальной шириной 320px и максимальной шириной 1fr, что означает 1 долю доступного свободного пространства. Вы можете думать о fr как о «частях» в рецепте коктейля, например:

grid-template-columns: 3fr 2fr 1fr;

будет похож на рецепт, который требует 3 части коньяка, 2 части тройной секунды и 1 часть свежего лимонного сока. Он ничего не говорит вам об объеме коктейля, который вы собираетесь приготовить, а только о том, в каком соотношении должны быть ингредиенты по отношению друг к другу и в целом.

С помощью repeat и auto-fill мы говорим браузеру повторять наш столбец гибкого размера столько раз, сколько поместится в #app div (который в нашем случае составляет 100% окна браузера). Вы заметите, что это делает нашу сетку полностью отзывчивой, без единого медиа-запроса!

Остальная часть CSS довольно проста. Одно хорошее сокращение, используемое в нескольких местах:

grid-column: 1 / -1;

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

grid-column-start: 1;
grid-column-end: -1;

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

Заворачивать

Смотрите полный код на Gist.

Это супер-быстрый старт в простой галерее Instagram, которая демонстрирует простоту использования и мощь как Vue.js, так и CSS Grid.

Есть много улучшений и дополнительных функций, которые вы могли бы включить сюда: более привлекательный стиль (кто угодно смотрит на поляроид?); отображение дополнительных данных, таких как лайки, подписи и теги; более надежная обработка ошибок и резервные версии для старых браузеров.

Какие улучшения вы бы внесли? Оставьте комментарий ниже! Если эта статья вам чем-то помогла, как насчет пары хлопков в ладоши?

Ресурсы для получения дополнительной информации: