Nuxt.js 无法从 asyncData() 更新 head() 属性

Nuxt.js cannot update head() properties from asyncData()

我使用 Nuxt.js 和 Typescript 和 Ghost 创建了一个服务器端呈现的 Vue.js 博客,但我在使用来自 [=12= 的数据更新 html 元标记时遇到了一些问题].

从 Nuxt.js 文档中我知道 asyncData() 每次在加载页面组件并与组件数据合并之前都会被调用。

我收到这个错误:

属性 'title' 不存在于类型 '{ asyncData({ app, params }: Context): Promise<{ title: string |不明确的;摘录:字符串 |不明确的; feature_image:可为空 |不明确的; html:可为空 |不明确的; }>;头():任何; }'.

这是我的代码:

<script lang="ts">
import { Context } from '@nuxt/types'
import { PostOrPage } from 'tryghost__content-api'

export default {
  async asyncData ({ app, params }: Context) {
    const post: PostOrPage = await app.$ghost.posts.read(
      {
        slug: params.slug
      },
      { include: 'tags' }
    )

    return {
      title: post.title,
      excerpt: post.excerpt,
      feature_image: post.feature_image,
      html: post.html
    }
  },

  head () {
    return {
      title: this.title,
      meta: [
        {
          hid: 'description',
          name: 'description',
          content: this.excerpt
        }
      ]
    }
  }
}
</script>

我已经尝试了一些解决方案,例如使用 data() 为每个项目设置默认值,但没有尝试。你有什么建议吗?

如果没有像 nuxt-property-decorator 这样的 typescript 插件,您将无法获得对 nuxt 的 Typescript 支持(无论哪种方式,类型检查和自动完成仍然无法工作)。

这就是为什么 asyncDatafetch 应该 在组件选项中

@Component({
  asyncData (ctx) {
    ...
  }
})
export default class YourClass extends Vue {
...
}

而不是

@Component
export default class YourClass extends Vue {
  asyncData (ctx) {
    ...
  }
}

如果您仍想在组件 class 中使用 asyncData() 而不是设置选项,请参阅 this working example 使用 npm 模块 nuxt-property-decorator

这是实施@nonNumericalFloat 的建议后的工作代码:

import { Component, Vue } from 'nuxt-property-decorator'
import { Context } from '@nuxt/types'
import { PostOrPage } from 'tryghost__content-api'

import Title from '~/components/Title.vue'

@Component({
  components: {
    Title
  }
})
export default class Page extends Vue {
  post!: PostOrPage

  async asyncData ({ app, params }: Context) {
    const post: PostOrPage = await app.$ghost.posts.read(
      {
        slug: params.slug
      },
      { include: 'tags' }
    )

    return {
      post
    }
  }

  head () {
    return {
      title: this.post.title,
      meta: [
        {
          hid: 'description',
          name: 'description',
          content: this.post.excerpt
        }
      ]
    }
  }
}