4

我需要在 Nuxt 中为我的应用程序设置全局头,一些子页面会覆盖它。那些全局头需要包含翻译的数据。

seoHead.js用代码创建了文件:

import Vue from "vue";

export const $t = (sign) => Vue.prototype.$nuxt.$options.i18n.t(sign);

export default {
  title: $t("seoGlobal.title"),
  meta: [
    { charset: "utf-8" },
    { name: "viewport", content: "width=device-width, initial-scale=1" },
    {
      hid: "description",
      name: "description",
      content: $t("seoGlobal.description"),
    },
    {
      hid: "ogSiteName",
      name: "og:site_name",
      content: "Test Page",
    },
    {
      hid: "ogTitle",
      name: "og:title",
      content: $t("seoGlobal.ogTitle"),
    },
    (...)
  ],
};

我在我的index.vue页面和其他页面中导入并使用这些数据,如下所示:

import seoHead from "~/constants/seoHead";

export default {
  head() {
    const metaI18n = this.$nuxtI18nSeo();
    const currentPath = process.env.LP_URL + this.$router.currentRoute.fullPath;
    return {
      ...seoHead,
      meta: [
        {
          hid: "ogLocale",
          name: "og:locale",
          content: metaI18n.meta[0].content,
        },
        {
          hid: "ogLocaleAlternate",
          name: "og:locale:alternate",
          content: metaI18n.meta[1].content,
        },
        {
          hid: "ogUrl",
          name: "og:url",
          content: currentPath,
        },
      ],
    };
  },
(...)

不幸的是,我面临Cannot read property '$options' of undefined错误。这对我来说很奇怪,因为我已经export const $t = (sign) => Vue.prototype.$nuxt.$options.i18n.t(sign);在另一个 js 文件中使用了代码。有谁知道为什么会出现这个错误?您知道翻译全局头部选项的最佳方式吗?

4

2 回答 2

4

正如评论中所讨论的,Nuxt 生命周期和您的组件似乎存在时间问题:在您的组件seoHead.js被导入时,Nuxt 尚未将其$nuxt对象注入Vue. 因此,一个简单的解决方法是延迟$t函数的执行(访问$nuxt):

  1. 更改您的组件以导出返回对象的函数,而不是直接导出对象:
export default function() {
  return {
    title: $t("seoGlobal.title"),
    // ...
  }
}
  1. index.vue中,将您的head函数更改为seoHead在传播时调用:
return {
  ...seoHead(),
  // ...

这样,访问的代码$nuxt将在稍后执行——不是在seoHead导入时执行,而是仅在head执行函数时执行。此时,Nuxt 生命周期有望完成启动工作,所需对象已到位。


正如我所说,这只是一种解决方法;如果您要head立即调用 in index.vue,则会出现相同的错误。因此,除非您找到一种合适的方法来集成到 Nuxt 生命周期中,否则我建议您也为您的翻译功能提供保障:

const $t = (sign) => Vue.prototype.$nuxt 
  ? Vue.prototype.$nuxt.$options.i18n.t(sign)
  : sign

如果所需的基础设施尚未到位,这将返回 i18n 密钥。不是很好,但比例外更好;)

或者,您可以直接导入您的 i18n 功能,而无需通过 Nuxt;这样你就不会对基础设施有任何依赖——好多了。

于 2021-02-28T17:13:48.207 回答
0

我认为您在这里基本上需要的是mixin

export default {
  title: $t("seoGlobal.title"),
  meta: this.computedMeta,
  computed:{
    computedMeta(){
      return [....] // this contains the array of objects in meta
   }
  }
  methods:{
   yourMethod(sign){
     return this.$nuxt.$options.i18n.t(sign);
   }
  }
};

然后只需将其作为 mixin 导入到您需要的任何文件中。

于 2021-02-24T18:23:49.083 回答