Nuxt.js: 如何从布局中引用页面数据? (例如,填充 og:title 标签)

Nuxt.js: How to reference page data from a layout? (e.g., to populate og:title tags)

我正在使用 Nuxt.js 生成静态页面。我希望每个页面都有一个唯一的 <title> 标签和 <meta property="og:title" ... > 标签。

当前实施

我目前有一个丑陋的解决方案来生成这些标签。我有两个页面如下所示:

pages/foo.vue

export default {
  head: {
    title: 'Foo',
    meta: [
      {
        property: 'og:title',
        content: 'Foo',
      },
    ],
  }
};

pages/bar.vue

export default {
  head: {
    title: 'Bar',
    meta: [
      {
        property: 'og:title',
        content: 'Bar',
      },
    ],
  }
};

问题

这为我的每个页面正确生成了 <meta property="og:title" ...> 标签,但它迫使我在所有页面上包含冗余代码。我的 og:title 标签总是匹配我的 <title> 标签,所以在每个页面上独立地重新定义它们是没有意义的。

所需的解决方案

我想要一个允许我在 layouts/default.vue 文件甚至 nuxt.config.js 中定义 og:title 标签的解决方案。像这样:

layouts/default.vue

export default {
  head() {
    return {
      meta: [
        {
          property: 'og:title',
          content: this.$page.head.title, // <-- This variable doesn't really exist
        }
      ],
    };
  },
};

pages/foo.vue

export default {
  head: { title: 'Foo' }
};

pages/bar.vue

export default {
  head: { title: 'Bar' }
};

问题

是否可以消除此处的样板文件?

更一般地说,Nuxt 布局是否可以引用特定于页面的数据?

A Layout.vue 无法直接访问来自 Page.vue 的 nuxt 数据。
您必须使用 Store 才能在它们之间共享数据。
参见 https://nuxtjs.org/guide/vuex-store/


关于您的初始请求,您可以使用 Mixin 在每个 Page.vue 上共享您的元配置。
参见 https://vuejs.org/v2/guide/mixins.html

例如

// mixins/meta.vue

<script>
export default {
  data () {
    return {
      title: null,
      description: null
    }
  },
  head () {
   return {
     title = this.title
     meta = [
      { hid: 'description', name: 'description', content: this.description },
      { hid: 'og:title', property: 'og:title', content: this.title },
      // ...
    ]
  }
}
</script>

// <Page>.vue with local mixin

<script>
import Meta from '~/mixins/meta'

export default {
  mixins: [Meta], // local mixin
  asyncData () {
    return {
      title: "Foo",
      description: "lorem ipsum",
    }
  }
}
</script>

或者使用 Nuxt 插件创建全局混合:

// plugins/meta.js

import Vue from 'vue'

Vue.mixin({
  data: { // ... }
  head: { // ...}
})

并声明要在每个页面上应用的新插件:

// nuxt.config.js

plugins: ['~/plugins/meta'],