Nuxt-content无法在组件的asyncData中正常工作的问题咨询
问题原因与解决方案
核心问题:Nuxt.js 的 asyncData 钩子仅在 pages 目录下的页面组件中生效,components 目录下的普通组件不支持这个钩子,所以你在 menu.vue 里用它获取内容不会执行。
下面是三种可行的解决方法:
方法1:从页面组件传数据到子组件
在能正常获取数据的页面组件(比如 index.vue)中拿到 articles,再通过 props 传递给 menu 组件:
- 页面组件(pages/index.vue)修改:
<template> <div> <!-- 把articles传给menu组件 --> <menu :articles="articles" /> </div> </template> <script> export default { async asyncData ({ $content }) { const articles = await $content('blog') .only(['title', 'description', 'img', 'slug']) .sortBy('createdAt', 'asc') .fetch() return { articles } } } </script>
- 菜单组件(components/menu.vue)接收 props:
<template> <!-- 原模板代码不变 --> </template> <script> export default { props: { articles: { type: Array, required: true } }, // 移除原来的asyncData,保留其他需要的逻辑 data () { return { num: this.$route.name } }, computed: { currentRouteName () { return this.$route.name } } } </script>
方法2:在组件中使用 fetch 钩子
Nuxt 2.12+ 支持在普通组件中使用 fetch 钩子,它和 asyncData 类似,但需要手动把数据赋值到组件实例上:
修改 menu.vue 的 script 部分:
<script> export default { data () { return { articles: [], num: this.$route.name } }, async fetch () { // 注意这里是this.$content,因为fetch钩子能访问组件实例 this.articles = await this.$content('blog') .only(['title', 'description', 'img', 'slug']) .sortBy('createdAt', 'asc') .fetch() }, computed: { currentRouteName () { return this.$route.name } } } </script>
注意:你的原代码中 $content('blog', params.slug) 是获取单篇文章的写法,菜单组件应该是要获取所有博客文章,所以去掉第二个参数 params.slug。
方法3:用 Vuex 统一管理数据
如果多个组件都需要用到博客列表数据,可以把获取逻辑放到 Vuex 中:
- 创建 store 文件(store/blog.js):
export const state = () => ({ articles: [] }) export const mutations = { SET_ARTICLES (state, data) { state.articles = data } } export const actions = { async fetchArticles ({ commit }) { const articles = await this.$content('blog') .only(['title', 'description', 'img', 'slug']) .sortBy('createdAt', 'asc') .fetch() commit('SET_ARTICLES', articles) } } export const getters = { getArticles: state => state.articles }
- 在 menu.vue 中调用并获取数据:
<script> export default { data () { return { num: this.$route.name } }, async created () { await this.$store.dispatch('blog/fetchArticles') }, computed: { currentRouteName () { return this.$route.name }, articles () { return this.$store.getters['blog/getArticles'] } } } </script>
内容的提问来源于stack exchange,提问作者Aurore
相关产品推荐
相关产品推荐

