Обо мне

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

Почесывая собственный зуд

Как новый разработчик-фрилансер, я создавал (и все еще работаю) небольшое приложение для улучшения своего портфолио. Там я столкнулся с проблемой использования клиента Google API (gapi).

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

Создание

Клиенту требуется сетевой вызов для загрузки фактического кода для запрошенного API.
Сначала браузер загружает и анализирует исходный сценарий для клиента. Затем ваше приложение отправляет запрос в конечную точку. Наконец, ответ возвращается, и API становится доступным на клиенте.

Глубокие ссылки

myapp.com/customers/online/1

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

Асинхронность

Каждый раз, когда мы открываем глубокую ссылку, браузер создает экземпляр всего одностраничного приложения (SPA). Если этот экран загружает ресурсы до или сразу после обработки, клиент gapi еще не готов.

Решение: загрузка API

Вот пример того, как загрузить клиент Auth2 для gapi. После получения ответа мы можем разрешить пользователю войти / зарегистрироваться через Google.
Обратите внимание, что мы получаем обратный вызов вместо обещания.

Теперь давайте запросим код для API электронных таблиц.

На этом этапе пользователь может войти в приложение через учетную запись Google. После этого приложение может работать с данными электронной таблицы пользователя.
Что касается программного обеспечения, у нас есть первый запрос, который возвращает обратный вызов. Внутри этого обратного вызова есть еще один запрос, который возвращает обещание. После выполнения обещания наш гапи-клиент готов.

Работа внутри метода spreadsheetReady приведет к большему количеству вложенного кода. Тем не менее, мы все еще хотим знать, когда клиент gapi готов, прежде чем пытаться использовать API электронных таблиц или Auth2.

Обертывание логики создания экземпляра вокруг обещания
Решение простое: оберните приведенный выше код в обещание и resolve его, передав сам экземпляр gapi.

Теперь у нас есть обещание, что вернет клиент gapi с кодом API для Auth2 и электронных таблиц. Теперь мы можем вызвать .then для этой переменной внутри методов для нашего компонента.
Ниже приведен пример, в котором мы разрешаем обещание двумя разными методами для данного компонента.

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

Проблема № 2: создается более одного раза

Произошла глубокая компоновка, клиент готов, и приложение использует API. Теперь пользователь переходит на другой экран, где компоненту также требуются API. Мы скопировали туда код, и приложение снова создает экземпляры API. Чтобы выполнить этот код только один раз, мы создадим плагин.

Решение: разделение опасений и абстракции

Создайте абстракцию для загрузки и инициализации

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

Для нашего плагина gapi мы создадим метод экземпляра Vue: $getGapiClient.

plugin / index.js

components / ClientList.vue

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

Простая версия

Мы начинаем с загрузки gapi.js, который является загруженным файлом сценария для клиента.
Когда плагин получает запрос на экземпляр клиента, возможны три случая.

  1. Это первый запрос - ›инициализируем клиента и возвращаем его.
  2. Клиент уже проинициализирован - ›возвращаем.
  3. Клиент ожидает ответа - ›мы возвращаем клиента, как только получим ответ.

Процесс развития

При разработке плагина я поместил код в сам проект. Структура проекта приведена ниже.

Папка ORM содержит код для использования API, когда клиент gapi готов. Эта бизнес-логика также является плагином, но отделена от служебной программы. Когда VueGAPI был стабильным, я решил сделать его доступным через NPM. Таким образом, я могу повторно использовать его в будущих проектах, и вы тоже.

Публикация плагина

Чтобы упростить публикацию, я искал шаблон vue-cli. Большинство из них касалось упаковки компонентов в плагин. Кроме того, все они использовали Webpack, но я хотел вместо этого использовать Rollup, поскольку он выводит меньше кода котла.

Мне удалось найти один из psova, Шаблон плагина Vue. После некоторой очистки я отправил свой код в NPM за считанные минуты!
Спасибо psova.

Следующие шаги

Оттуда, вот следующие шаги:

  • отвечать на отзывы и улучшать код и этот пост
  • работа над функциями аутентификации
  • напишите еще один пост о расширении с VueGAPI

Отзывы и вклад

Мы очень ценим обратную связь!

Чтобы внести свой вклад, смело создавайте PR репо: VueGAPI.

Удачного кодирования!

Первоначально опубликовано на www.codementor.io.