От автора: сегодня речь пойдет о библиотеке Vue js VueX и о том, как с ее помощью можно решить некоторые проблемы взаимодействия Frontend и API. Увеличение сложности разработки веб-сайтов в конце концов привело к увеличению объема специализации и разделению front end и back end.
Эта специализация и повышенная сложность имеют ряд преимуществ: качество пользовательского опыта в Интернете увеличилось экспоненциально, одновременно увеличивая количество людей на разных типах устройств, чем когда-либо в истории. Однако это также вызывает ряд проблем.
Задача: взаимодействие между Frontend и API
Интерфейс между интерфейсом и API стал общей точкой трения, задач и сложности. В идеальном мире backend и frontend будут развиваться вместе в гармонии, с тесной связью, а данные, обслуживаемые backend, будут соответствовать именно тем, что нужно frontend.
В действительности, часто две части приложения разрабатываются совершенно разными командами или даже разными компаниями. Совсем нередко есть специализированная команда в агентстве, создающая дизайн и интерфейс, в то время как ваша собственная команда разработчиков работает над backend.
Типичные решения
Результатом является поток, который обычно выглядит следующим образом:
Создайте пользовательский интерфейс с использованием поддельных «заштрихованных» данных, либо непосредственно встроенных в шаблоны и код, либо загруженных через набор фикстур.
Когда API готов, скремблируйте, чтобы заменить каждую точку интеграции реальными вызовами API и данными.
Проблемы с этим подходом двоякие:
Интеграция данных часто разбросана по всему приложению, требуя отслеживания и обработки тонны кода.
Даже если данные относительно изолированы, часто возникает несоответствие между ожидаемым интерфейсом и тем, что API в конечном итоге предоставляет.
Существует лучшее решение: VueX
Если вы разрабатываете свой внешний интерфейс с помощью Vue.js, лучшее решение этой проблемы прямо у вас под рукой.
Библиотека VueX, глубоко интегрированная в Vue, обеспечивает идеальное решение для создания чистого, изолированного интерфейса к вашим данным, что делает переход между заштрихованными данными и реальным API легким.
Что такое VueX
VueX — это библиотека управления состоянием, вдохновленная Flux, Redux и архитектурой Elm, но специально спроектированная и настроенная на то, чтобы хорошо интегрироваться с Vue.js и использовать преимущества Vue’s Reactivity.
Все эти библиотеки направлены на решение простой проблемы: когда есть состояние, которое разделяется между многими компонентами, особенно компонентами, которые являются братьями или сестрами или в самых разных представлениях, управление распределением и обновлением этого состояния является сложной задачей.
Библиотеки, такие как VueX, позволяют управлять общим состоянием между компонентами способом, который структурирован и поддерживается, путем создания глобального дерева состояний, к которому можно получить доступ и обновить каждый компонент структурированным способом.
Как работает VueX
VueX делит управление состоянием на 3 ключевые части: состояние, мутации и действия . Когда вы создаете экземпляр хранилища VueX, вы определяете эти три объекта:
1 2 3 4 5 6 7 8 9 10 11 |
const store = new Vuex.Store({ state: { ... }, mutations: { ... }, actions: { ... } }) |
Состояние
Состояние представляет собой фактические данные. Это просто объект JavaScript, содержащий дерево данных. В VueX вы можете иметь одно глобальное дерево состояний или организовывать по модулю (например, дерево состояний пользователей, дерево состояний продукта и т. д.).
Например, мы можем использовать это дерево состояний для отслеживания нашего текущего пользователя, начиная с нуля, если пользователь не вошел в систему:
1 2 3 |
state: { currentUser: null } |
Мутации
Мутации — это механизм, с помощью которого мы меняем наше дерево состояний. Все изменения состояния должны проходить через мутации, что позволяет VueX управлять состоянием предсказуемым образом.
Пример мутации может выглядеть так:
1 2 3 4 5 |
mutations: { setCurrentUser(currentState, user) { currentState.currentUser = user; } } |
Мутации являются синхронными и непосредственно изменяют объект состояния (по сравнению с, например, Redux, где эквивалентная концепция называется редуктором и возвращает новый объект).
Это синхронное, прямое изменение состояния объекта идеально сочетается с концепцией реактивности Vue. Объекты состояния VueX являются реактивными, поэтому изменения пульсируют во всех зависимостях.
Вы вызываете мутацию через функцию commit:
1 |
store.commit('setCurrentUser', user); |
Действия
Действия — это заключительная часть VueX, посредника между намерением и модификацией.
Действия являются асинхронными и косвенно изменяют хранилище посредством committing мутаций. Однако, поскольку они асинхронны, они могут делать гораздо больше.
Asynchronicity позволяет действиям обрабатывать такие вещи, как вызовы API, взаимодействие с пользователем и целые потоки действий.
В качестве простого примера действие может вызвать вызов API и записать результат:
1 2 3 4 5 6 7 |
actions: { login(context, credentials) { return myLoginApi.post(credentials).then((user) => { context.commit('setCurrentUser', user) }) } } |
Действия могут возвращать promises, позволяя представлениям или другому коду отправлять действия, чтобы дождаться их завершения и реагирования на основе их результатов. Вместо использования commit вы dispatch действие. Например, наш код вызова может выглядеть так:
1 2 3 4 5 |
store.dispatch('login', credentials).then(() => { // redirect to logged in area }).catch((error) => { // Display error messages about bad password }); |
Почему VueX-действия являются идеальным интерфейсом для API
Если вы работаете над проектом, в котором back end и front end одновременно развиваются, или вы работаете в команде UI / Frontend, которая может даже создавать пользовательский интерфейс до того, как back end существует, вы, вероятно, знакомы с проблемой, когда вам нужно заглушить части back end или данные по мере развития front end.
Общим способом, который это проявляется, является чисто статичные шаблоны или контент, с записями-заполнителями и текстом прямо в ваших интерфейсных шаблонах.
Шаг от этого — это некоторая форма фикстур, данные, которые статически загружаются интерфейсом и внедряются на место.
Оба они часто сталкиваются с одним и тем же набором проблем. Когда back end наконец-то доступен, есть куча рефакторинга, чтобы получить данные на месте.
Даже если (чудом) структура данных из back end соответствует вашим фикстурам, вам все равно придется скреститься, чтобы найти каждую точку интеграции. И если структура отличается (и давайте посмотрим правде в глаза, как правило, это так), вы не только должны это сделать, но вы должны выяснить, как вы можете либо изменить внешний интерфейс, либо создать слой абстракции, который преобразует данные.
Знакомство с действиями VueX
Красота VueX заключается в том, что действия обеспечивают идеальный способ изолировать и абстрагироваться между front end и back end, а также делать это таким образом, чтобы обновление от заштрихованных данных до реального back end было простым.
Позвольте мне немного расширить. Давайте рассмотрим наш пример авторизации. Если наш API входа еще не существует, но мы все еще готовы создать интерфейс, мы могли бы реализовать наши действия так:
1 2 3 4 5 6 7 8 9 10 11 |
actions: { login(context, credentials) { const user = MY_STUBBED_USER; if(credentials.login === 'works@test.com') { context.commit('setCurrentUser', user) return Promise.resolve(); } else { return Promise.reject(new Error('invalid login')); } } } |
Теперь наш front-end может реализовать логин, который ведет себя точно так, как он будет в будущем, с тестовыми данными, позволяющими как успех, так и неудачу. Поведение будет происходить немедленно, а не асинхронно через API, но, возвращая promises, теперь все вызывающие абоненты могут обращаться с ним так же, как и для реального вызова API.
Когда наш API доступен, мы можем просто изменить это действие, чтобы использовать его, а все остальное в нашей базе кода остается прежним.
Обработка несоответствий данных
Изоляция вызовов API на VueX также дает нам прекрасный и чистый способ обработки несоответствий в формате данных между back end и front end.
Продолжая наш пример входа, возможно, мы предположили, что API вернет всю информацию пользователя, которая нам нужна при входе в систему, но вместо этого нам нужно получить предпочтения с отдельной конечной точки после аутентификации, и даже тогда формат отличается от того, что мы ожидали.
Мы можем полностью исключить это несоответствие в рамках нашего VueX-действия, не позволяя нам ничего менять в нашем интерфейсе. Поскольку promises могут быть скованными и вложенными, мы можем пройти ряд вызовов API, которые все должны выполнить, прежде чем наше действие будет считаться завершенным.
1 2 3 4 5 6 7 8 9 10 11 |
actions: { login(context, credentials) { return myLoginApi.post(credentials).then((userData) => { const user = { ...userData }; return myPreferencesApi.get(userData.id).then((preferencesData) => { user.preferences = transformPreferencesData(preferencesData); context.commit('setCurrentUser', user) }); }) } } |
Конечный результат с точки зрения как наших изменений состояния, так и кода, который отправляет наше действие для login точно так же.
С VueX проблема интеграции нового или изменяющегося API-интерфейса в нашем front end была значительно упрощена.
PS — Если вас интересуют эти темы, я отправляю еженедельную новостную рассылку «Пятничный front end». Каждую пятницу я отправляю 15 ссылок на лучшие статьи, учебные пособия и объявления в CSS / SCSS, JavaScript и множество других потрясающих Front-End новостей. Зарегистрируйтесь прямо сейчас!
Источник: //zendev.com/
Редакция: Команда webformyself.