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

Posted

技术标签:

【中文标题】无法读取未定义的属性 \'$options\' 为头选项制作外部 js 文件【英文标题】:Cannot read property '$options' of undefined making external js file for head options无法读取未定义的属性 '$options' 为头选项制作外部 js 文件 【发布时间】:2021-05-23 07:54:14 【问题描述】:

我需要在 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); 代码。有谁知道为什么会出现这个错误?您知道翻译全局 head 选项的最佳方式吗?

【问题讨论】:

我对 Nuxt 不太熟悉,但您的错误消息似乎表明存在竞争条件:在 Nuxt 的设置完成之前使用了 seoHead,因此尚未定义(注入)$nuxt然而,当它在$t 中被访问时。你能排除这种情况吗? @dr_barto 可能是。我在 Nuxt 生命周期方面不是很有经验:/ 请检查您是否在其他地方导入了seoHead.js,如果发现任何导入,请尝试删除该导入。这不太可能,但是..好吧:) 仅在我导入的描述文件中seoHead.js 也许这种解决方法对您有用:通过更改 seoHead.js 来延迟执行 $t 以导出一个函数,该函数仅返回您当前正在导出的对象。然后,在index.vue 中,只需将行...seoHead 更改为...seoHead() 【参考方案1】:

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

    更改您的组件以导出返回对象的函数,而不是直接导出对象:
export default function() 
  return 
    title: $t("seoGlobal.title"),
    // ...
  

    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

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

或者,您也可以直接导入您的 i18n 功能,而无需通过 Nuxt;这样一来,您就完全不会依赖基础架构了——好多了。

【讨论】:

【参考方案2】:

我认为您在这里基本上需要的是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 导入到您需要的任何文件中。

【讨论】:

以上是关于无法读取未定义的属性 '$options' 为头选项制作外部 js 文件的主要内容,如果未能解决你的问题,请参考以下文章

使用Google Chart API获取“无法读取未定义的属性”vB'错误

无法读取未定义类型错误的属性“推送”:无法读取未定义错误的属性“推送”

我用win7系统,无法获取未定义或null引用的属性“options”

带有 Ionic 4 的 SQLite?无法读取未定义类型错误的属性“then”:无法读取未定义的属性“then”

`无法读取未定义的属性(读取'组件')`

NextJS:未捕获的类型错误:无法读取未定义的属性(读取“属性”)