Option 1: $fetchState.pending
Show loading at page component
<template> <div> <div v-if="$fetchState.pending">Loading ...</div> <div v-else-if="$fetchState.error">Error: {{ $fetchState.error.message }}</div> <div> {{ title }} </div> </div></template><script>export default { async fetch() { // const HOST = 'http://localhost:8080' // required for server-side fetch // const url = new URL(`/data/test.json`, HOST) const url = 'https://jsonplaceholder.typicode.com/posts/1' // alternatvely, you could use $axios or $http const res = await fetch(url) const data = await res.json() this.title = data.title // sleep 5s // await new Promise(r => setTimeout(r, 5000)) }, data() { return { title: null } },}</script>
Option 2: $nuxt.$loading
Via nuxt loading property.
<template> <div> <div v-if="!$fetchState.pending && !$fetchState.error"> {{ title }} </div> </div></template><script>export default { loading: false, // disable default loading handling async fetch() { // show loading this.$nuxt.$loading.start() // const HOST = 'http://localhost:8080' // required for server-side fetch // const url = new URL(`/data/test.json`, HOST) const url = 'https://jsonplaceholder.typicode.com/posts/1' // alternatvely, you could use $axios or $http const res = await fetch(url) const data = await res.json() this.title = data.title // sleep 5s // await new Promise(r => setTimeout(r, 5000)) // hide loading this.$nuxt.$loading.finish() }, data() { return { title: null } },}</script>
Edit nuxt.config.js
to configure loading bar color and size.
export default { loading: { color: 'blue', height: '5px' }}
Option 3: Show Loading via Layout
Use master layout file to show loading.
Edit store/index.js
.
export const state = () => ({ loading: false})export const mutations = { loading(state, value) { state.loading = value }}export const actions = {}
Page component
<template> <div> <div v-if="!$fetchState.pending && !$fetchState.error"> {{ title }} </div> </div></template><script>export default { loading: false, // disable default loading handling async fetch() { // show loading this.$store.commit('loading', true) // const HOST = 'http://localhost:8080' // required for server-side fetch // const url = new URL(`/data/test.json`, HOST) const url = 'https://jsonplaceholder.typicode.com/posts/1' // alternatvely, you could use $axios or $http const res = await fetch(url) const data = await res.json() this.title = data.title // sleep 5s // await new Promise(r => setTimeout(r, 5000)) // hide loading this.$store.commit('loading', false) }, data() { return { title: null } },}</script>
Edit layouts/default.vue
<template> <div> <div v-if="loading">Loading ...</div> <nuxt/> </div></template><script>export default { computed: { loading() { return this.$store.state.loading } }}</script>