How to handle Nuxt.js asyncData with new composition API
by mmyoji
2 min read
[UPDATED: 2021-03-30]
We already have @nuxtjs/composition-api. It has useAsync function for the purpose.
Vue.js will introduce
new composition API (a.k.a.
function API). It's really great API but I wonder how to combine with Nuxt.js
asyncData
w/ this new API. I find solutions and write about it though Nuxt.js
might change its APIs.
A1. Use fetch
and Vuex
First, I thought I would use composition API's onBeforeMount
or onCreated
(you know
onCreated
API doesn't exist)
inside setup
.
BUT, asyncData
is not in Vue.js lifecycle. It's
a kind of vue-router's feature
I guess. The API fetches data when URI path changes and Nuxt.js will render(or
create) next page vm after fetching the data.
And if you use TypeScript, accessing this
inside vm is not good for it. I
don't like to write @ts-ignore
for the purpose.
So you can utilize context
arguments both fetch
(Nuxt.js) and setup
(composition API).
Then, when you want the web page behavior as the same, you use fetch
instead
of asyncData
and set the data in Vuex store through the context
. Nuxt.js
includes Vuex and you don't need to install additional packages.
ref
The sample code is like this: (the code is just an example, I haven't tried this yet)
// inside <script lang="ts"> of pages/foo.vue
import { createComponent, ref } from '@vue/composition-api'
export default createComponent({
async fetch({ store }) {
const res = await axios.get('http://my-api/stars')
store.commit('setStars', res.data)
}
setup(props, { root }) {
const store = root.$store
const stars = ref<Star[]>(store.state.stars)
return {
stars
}
}
})
I think this is better solution for the question.
A2. Use loading view
This is more general and simpler approach.
Prepare loader view and fetch data inside Vue.js lifecycle and show expected view after data is fetched.