无法读取未定义的 属性 '$options' 为 head 选项制作外部 js 文件

Cannot read property '$options' of undefined making external js file for head options

我需要在 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 错误。这对我来说很奇怪,因为我已经在另一个 js 文件中使用了 export const $t = (sign) => Vue.prototype.$nuxt.$options.i18n.t(sign); 代码。任何人都知道为什么会出现此错误?你知道翻译全局头选项的最佳方法吗?

我想你基本上需要的是 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 导入到您需要的任何文件中即可。

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

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

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


正如我所说,这只是一种解决方法;如果您在 index.vue 中立即调用 head,则会出现相同的错误。因此,除非你找到合适的方式集成到 Nuxt 生命周期中,否则我建议在你的翻译功能中也加入一个保护措施:

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

如果所需的基础设施尚未到位,这将 return 国际化密钥。不是很好,但总比例外好 ;)

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