Получение данных в Nuxt
Хук fetch наиболее универсальный способ получения данных. Может использоваться в компонентах, макета, страницах, выполнятся на стороне сервера и клиента.
The fetch hook
Хук fetch наиболее универсальный способ получения данных. Может
использоваться в компонентах, макета, страницах, выполнятся на стороне
сервера и клиента. Может вызываться повторно для обновления данных.
Имеет доступ к this компонента.
Отлично подходит для заполнения HTML данными, которые затем
должны обновляться, например таблицы, постраничные данные и т.д.
fetch должен возвращать promise или использовать механику async/await.
export default {
data () {
return {}
},
async fetch () {
this.news = this.$api.get('news').readMany()
}
} Полученные данные сохраняются в компоненте или во Vuex.store.
Размышления о fetch
Универсальность fetch() наводит на некоторые размышления и
вопросы о его работе.
Во-первых, на какой стадии жизненного цикла Nuxt выполняется запрос,
в каком окружении server или client? Это зависит от значений
параметра конфигурации ssr:
ssr: true, тогдаfetchвыполняется на стороне сервера, перед
началом отрисовки, если используетсяtarget: server, или на этапе
генерации статичного сайта приtarget: staticssr: false, тогдаfetchвыполняется на клиенте при загрузке маршрута
Если по каким-то причинам при ssr: true требуется отключить исполнение
fetch на сервере, это можно сделать установив fetchOnServer: false в
параметрах компонента. Можно ограничить время исполнения параметром
fetchDelay.
Чтобы обновлять данные при изменении параметров запроса, например
фильтры или пагинация:
export default {
watch: {
'$route.query': '$fetch'
}
}
fetch содержит несколько важных параметров
error- содержит ошибку, если запрос завершился неудачейpending- отражает состояние выполненияtrue|falsetimestamp- время последнего запроса, удобно для реализации кеширования
<template>
<div v-if='$fetchState.pending'>Please wait...</div>
<div v-else-if='$fetchState.error'>Oh no!</div>
<div v-else>
...
</div>
</template>
The asyncData hook
Загружает данные почти также как fetch, но со следующими различиями
- Может использоваться только в компонентах страниц
pages/**/*.vue - Объединяет полученные данные с данными компонента
- Не имеет доступа к
thisкомпонента
asyncData выполняется при смене маршрута, и разрешается до отрисовки
страницы, поэтому и нет доступа к контексту компонента, его просто
еще не существует.
Взамен, в хук передается контекст Nuxt.
Чтобы обновить asyncData, выполнить его снова придется
- обновить страницу целиком
- выполнить
this.$nuxt.refresh()
При этом this.$nuxt.refresh() обновит полностью все, включая asyncData
, fetch, перерисует страницу полностью. Поэтому, если надо только обновить
данные лучше использовать fetch.
asyncData отлично подходит для загрузки первичных данные страницы.
asyncData так же, как и fetch, не реагирует на изменения параметров
запроса, это нужно делать явно. Например,
export default {
watchQuery: ['someQSParam'] //or true for all
}
Когда параметр someQSParam поменяется, fetch() и asyncData() будут
запущены заново.
Vuex Actions
Еще один подход, использование действий Vuex. Можно использовать dispatch
для вызова асинхронных функций и получения данных. Это делает процесс
получения данных сложнее, но позволяет повторно использовать методы в
разных компонентах и хуках. Контроль за доступностью данных становиться
сложнее. Отрисовка и логика шаблонов требует проверки доступности данных,
или использования computed методов, для дополнительной проверки.
Router middleware
Если получение данных критично, данные должны быть доступны до отрисовки
компонента можно использовать middleware. Функции выполняются до
отрисовки и создания компонентов, данные не могут сохраняться напрямую
в компонентах, но могут быть сохранены во Vuex.store.
Использование middleware может потребоваться когда данные необходимы
на каждой странице проекта. Объявить middleware можно тремя способами:
- в конфигурации Nuxt (для определенного маршрута)
- в макетах (layout) (для страниц и определенного макета)
- в странице (page) (только для определенной страницы)