After a little head scratch, I found a way to easily update your data if you have a metadata you want to update in a Composition-Api powered Nuxt application, even when they are Async :
<template>
<div>Your content</div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted } from '@vue/composition-api'
import usePosts from '~/composables/use-posts'
export default defineComponent({
name: 'PageArticle',
head() {
return {
title: `${this.title}`,
meta: [
{ name: 'og:title', content: `${this.title}`, hid: 'og:title' },
]
}
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setup(props, ctx) {
const { fetchArticleForUserLang, article } = usePosts({ ctx })
const slug = ctx.root.$route.params?.article
let title = ref('Cuisine De Geek')
onMounted(async () => {
await fetchArticleForUserLang({ articleSlug: slug, subcategory: 'article' })
if (article.value) {
title.value = article.value[0].title
}
})
return { article, title }
}
})
</script>
Okay so break-it-down-time :
<template>
<div>Your content</div>
</template>
Nothing fancy here, just the init of your template content, if you want to display the data (could be a good idea at one point).
<script lang="ts">
import { defineComponent, ref, onMounted } from '@vue/composition-api'
import usePosts from '~/composables/use-posts'
Here, we import the method needed from the composition-api for everything to work correctly : defineComponent, ref to create a dynamic data later, and onMounted to do something as soon as this component/page is called.
The usePosts file called is a separate file I made to handle the logic of loading the data from a separate api (for the record here it's a wordpress REST api).
export default defineComponent({
name: 'PageArticle',
head() {
return {
title: `${this.title}`,
meta: [
{ name: 'og:title', content: `${this.title}`, hid: 'og:title' },
]
}
},
Ah, the big part ! Here, we define the name of our component, then we tell it to change the <head>
section of our page.
Because Nuxt use Vue-Meta by default, we can use the head() method in our defineComponent.
Great so now we tell it to use this.title
to replace title of the page and og:title
. But where do we load this data in particular ?
Well in our setup !
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setup(props, ctx) {
const { fetchArticleForUserLang, article } = usePosts({ ctx })
const slug = ctx.root.$route.params?.article
let title = ref('Cuisine De Geek')
Here, first I tell eslint to stop bothering me with the fact that I don't use props in this case.
Then i want to get my method fetchArticleForUserLang
and the data article
that the method will load later.
I store the slug from the route to call the correct article from this slug later and then I set a variable title that is a ref to be able to update it later on a different life cycle of the application :
onMounted(async () => {
await fetchArticleForUserLang({ articleSlug: slug, subcategory: 'article' })
if (article.value) {
title.value = article.value[0].title
}
})
return { article, title }
When the component or page (here a page), we tell it to be async to be able to await for our method fetchArticleForUserLang
to actually find the data and set it to the article variable (all made behind the scene in the usePosts
file).
We check that the article have an actual data (.value since it's a ref) then we tell it to assert the value of the title to our brand new article title.
We finish of by returning our article value and our title ET VOILA.
Top comments (0)