Я думаю, здесь есть две основные идеи, которые нужно понять.Я опишу оба.
1.Общий метод извлечения данных без блокирования рендеринга
Похоже, вы понимаете эту концепцию на уровне родительских компонентов, но затем спрашиваете, как сделать нечто очень похожее для дочерних компонентов, содержащихся на этой странице.
То, как я справляюсь с этим, находится в моем компоненте, мои данные по умолчанию находятся в состоянии isLoading.Затем в beforeMount()
или mounted()
я выполняю свои асинхронные действия и вносю необходимые изменения в данные своей страницы.
Проблема становится полностью рекурсивной, когда мы смотрим на дочерние компоненты.Вы хотите убедиться, что ваши дочерние компоненты выполняют рендеринг, и что любая длительная выборка данных, которая должна происходить в их реализации, просто заставит их повторно выполнить рендеринг после завершения выборки.
Вотрабочий пример: https://codesandbox.io/embed/r4o56o3olp В этом примере используется Nuxt.Помимо методов fetch () и asyncData (), остальные хуки жизненного цикла Vue здесь одинаковые.
Я использую new Promise
и setTimeout
, чтобы продемонстрировать операцию, которая будет использовать обещания и бытьасинхронный.(например, axios.get(..)
)
Страница About загружается, а хук жизненного цикла beforeMount()
выполняет асинхронную выборку так, чтобы не блокировать отображение страницы.
Я используюbeforeMount()
ловушка, потому что, согласно (1028 *https://alligator.io/vuejs/component-lifecycle/), это первая ловушка жизненного цикла, к которой мы имеем доступ, как только данные страницы реагируют.(Таким образом, изменение this.myDataProp
вызовет повторную визуализацию, если в шаблоне будет использоваться {{ myDataProp }}
).
Я также включил дочерний компонент, где я намеренно заставил его данные загружаться в два раза дольше.Поскольку я снова позволяю компоненту визуализироваться немедленно, а , а затем Я занимаюсь извлечением / обновлением данных в соответствующем хуке жизненного цикла, я могу управлять, когда конечный пользователь воспринимает страницу для загрузки.
В моем рабочем примере LongLoadingComponent
выполнял ту же самую технику, что и страница About.
Как только вы увидите, как использовать beforeMount()
или mounted()
для извлечения данных, а затем для обновления состояния,Я думаю, хитрость заключается в том, чтобы занять мгновение и по-настоящему задуматься о состоянии по умолчанию вашего компонента.Когда он впервые рендерится, что должен увидеть пользователь перед завершением каких-либо операций извлечения данных / выполнения длительных операций?
Как только вы определите, как должен выглядеть компонент по умолчанию (еще не загруженный), попробуйте получить его ввизуализируйте на экране и добавьте в логику, которая выбирает и обновляет данные о состоянии.
2.Прослушивание, когда дочерний компонент заканчивает рендеринг из родительского компонента
. В нем используется описанная выше методика, но при этом используется ловушка updated()
и отправляется пользовательское событие (https://vuejs.org/v2/guide/components-custom-events.html)
Если вы действительно хотите прослушать , когда ваши дочерние компоненты закончат рендеринг, вы можете $emit
пользовательское событие в вашем updated()
хуке.Возможно, что-то вроде этого (в одном из ваших дочерних компонентов)
if (this.dataLoaded) { this.$emit('loadedAndRendered') }
Так что, когда асинхронные операции дочернего элемента выполнены, он может перевернуть его свойство dataLoaded
в true.Если dataLoaded
где-то используется в дочернем <template>
, то компонент должен повторно выполнить рендеринг (поскольку он находится в состоянии «закончено»).Когда ребенок повторно рендерится, крючок updated()
должен сработать.(снова см .: https://alligator.io/vuejs/component-lifecycle/) Я включил часть if (this.dataLoaded)
только для обработки случая, когда хук updated()
может быть вызван во время промежуточных обновлений данных.(Мы хотим выдать событие loadedAndRendered
, если дочерний элемент завершил загрузка данных / обновление.)
3.Другие предупреждения об универсальных приложениях nuxt
Только после того, как я написал этот ответ, я понял, что вы не используете Nuxt.Однако я добавляю это в случае, если другие пользователи Nuxt сталкиваются с этим.
Я добавляю этот раздел только потому, что мне понадобилось некоторое время для того, чтобы обернуть голову.Универсальное приложение Nuxt выполняет рендеринг как на стороне сервера, так и на стороне клиента.Поначалу мне было немного трудно понять, когда что-то отображается на клиенте, а не на сервере.В рабочем примере, на который я ссылался выше, когда вы посещаете страницу о программе, вы также можете увидеть, был ли этот компонент извлечен с сервера или он только что был обработан клиентом.
Я бы порекомендовал поиграть со страницами.методы fetch () и asyncData () и посмотрите, как они влияют на отображение определенных вещей на вашем экране.(https://nuxtjs.org/api/pages-fetch/) (https://nuxtjs.org/api/).Просмотр того, для чего эти методы полезны, помогает мне также определить, для чего они not .
Если вы используете магазин Vuex, я бы порекомендовал посмотретьчто происходит, когда вы обновляете страницу или используете вместо нее навигацию между страницами.(Видеть что-то похожее на диаграмму схемы SSR может быть полезно здесь: https://nuxtjs.org/guide#schema)
.. Мне еще предстоит полностью оценить детали поведения комплектации и доставки, которое Webpack предоставляет для приложения Universal Nuxt(Смотрите правую часть схемы здесь: https://medium.freecodecamp.org/universal-application-code-structure-in-nuxt-js-4cd014cc0baa)