Как запросить данные в универсальном веб-приложении

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

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

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

Что нужно знать перед чтением:

Жизненный цикл маршрута

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

Распределите свои данные по категориям

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

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

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

Ленивый - дополнительные данные, которые не критичны для взаимодействия с пользователем. Эти данные должны запрашиваться после критических данных и не должны блокировать рендеринг.

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

На самом деле… Четыре жизненных цикла маршрута

Как оказалось, в универсальном веб-приложении Vue любой маршрут может иметь четыре разных жизненных цикла маршрутизации. Вот краткое описание жизненных циклов и их основных различий:

Запрос сервера

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

Инициализация клиента

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

Клиентская навигация

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

Навигация по обновлению клиента

То же, что и жизненный цикл клиентской навигации, за исключением того, что пользователь переходит к маршруту, который использует те же компоненты, что и текущий маршрут (например, / profile / 123 / - ›/ profile / 456 /). В этом случае вызывается другой набор перехватчиков обновления, потому что маршрут уже введен и компоненты уже созданы.

Давайте обновим нашу модель.

Крючки жизненного цикла

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

Несколько замечаний об этой диаграмме:

  • Подтверждение навигации подразумевается в ловушке onReady, если согласованный маршрут не отклонен.
  • beforeEach, beforeResolve и afterEach, как правило, предназначены для навигации на клиенте.
  • Перехватчики жизненного цикла beforeRouteLeave, beforeDestroy и уничтожено, которые вызываются во время жизненного цикла клиентской навигации, намеренно не учитываются. Эти хуки вызываются в конце жизненного цикла маршрута, что делает их не лучшим выбором для запроса данных.

Какие крючки мне использовать?

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

Проблемы, возникающие после устранения компонентов

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

ДИСКВАЛИФИЦИРОВАНО: beforeEach, beforeEnter

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

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

ДИСКВАЛИФИЦИРОВАНО: beforeEnter, beforeRouteEnter, beforeCreate, создано

Перехватчики, согласованные между навигацией клиента и навигацией по обновлению клиента

Затем мы можем дисквалифицировать любые хуки жизненного цикла, которые несовместимы между жизненными циклами клиентской навигации и клиентской навигации по обновлению. Если вы поместите логику запроса в эти хуки, ваши данные либо не будут запрошены в одном из жизненных циклов, либо вам придется повторять логику запроса для нескольких хуков жизненного цикла.

ДИСКВАЛИФИЦИРОВАНО: beforeEnter, beforeRouteEnter, beforeRouteUpdate, beforeCreate, created, watch $ route, beforeMount, смонтирован, beforeUpdate, обновлен

Что у нас осталось?

Смогут ли хуки onReady, beforeResolve и afterEach запрашивать данные, как описано в нашей модели? Безусловно, с помощью некоторых настраиваемых перехватчиков компонентов маршрута.

Крючки компонентов маршрута

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

Связывая все вместе

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

В нашем жизненном цикле серверного запроса мы можем использовать ловушку жизненного цикла onReady для вызова перехватчиков разрешений и компонентов маршрута критических данных.

В нашем жизненном цикле инициализации клиента мы можем использовать ловушку жизненного цикла onReady для вызова ловушки компонента маршрута lazyData. Мы также можем подписаться на хуки жизненного цикла beforeResolve и afterEach, которые будут вызывать перехватчики компонентов маршрута permissions, criticalData и lazyData во время последующей навигации.

Давайте посмотрим, как все взаимосвязано на примере кода.

Код

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

Точка входа на сервер

Клиентская точка входа

Пример компонента маршрута

Преимущества перехватов компонентов маршрута

Разделение кода. Весь код конкретного маршрута для запроса данных может находиться в компонентах маршрута, поэтому его можно легко разделить на код.

Читаемость. Посмотрев на компонент маршрута, можно легко определить места, где запрашиваются данные для маршрута.

Обслуживаемый - код для запроса данных добавляется в предсказуемый набор функций при проектировании компонентов маршрута и будет работать на всех жизненных циклах маршрута.

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

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

Хотя эта статья содержит самоуверенные модели и примеры кода, общие идеи гибки, и я бы посоветовал вам адаптировать их для своих собственных целей.

Надеюсь, эта статья оказалась для вас полезной, и мне не терпится услышать мысли сообщества Vue.