如何使用 Apollo 在 Nuxt 生成的动态页面中正确填充页眉?
Posted
技术标签:
【中文标题】如何使用 Apollo 在 Nuxt 生成的动态页面中正确填充页眉?【英文标题】:How to properly populate page headers in Nuxt generated dynamic pages using Apollo? 【发布时间】:2019-09-29 18:48:35 【问题描述】:我有一个 Nuxt.js,它是静态生成的站点,其中包含一些动态页面。我正在使用基于 GraphQL 的无头 CMS (DatoCMS) 为这些页面提供数据,这些页面使用 Apollo (@nuxt/apollo) 访问。我让它正确生成所有路线,但是当我从我的站点导航导航到这些页面时,我收到以下错误 3 次:
TypeError: Cannot read property '_seoMetaTags' of undefined
at f.head (cf150f1920d36ab67139.js:1)
at wn.get (008dfc959ff6e6a713a0.js:2)
at wn.evaluate (008dfc959ff6e6a713a0.js:2)
at f.$metaInfo (008dfc959ff6e6a713a0.js:2)
at f.created (008dfc959ff6e6a713a0.js:2)
at Qt (008dfc959ff6e6a713a0.js:2)
at fn (008dfc959ff6e6a713a0.js:2)
at f.t._init (008dfc959ff6e6a713a0.js:2)
at new f (008dfc959ff6e6a713a0.js:2)
at 008dfc959ff6e6a713a0.js:2
这来自我的页面组件中的头部代码,因此很明显有些东西没有正确生成。我还可以在 Chrome 网络选项卡中看到正在对 GraphQL 接口进行调用,这也告诉我静态生成工作不正常。
这是我的页面组件的 head() 和 apollo 部分:
head()
return
title: this.blogPost._seoMetaTags.find(element =>
return element.tag === 'title';
).content,
meta: [
hid: 'keywords', keywords: this.blogPost.keywords ,
hid: 'description', description: this.blogPost._seoMetaTags.find(element =>
return element.tag === 'meta' && element.attributes.name === 'description';
).attributes.content
],
script: [
src: 'https://cdn.commento.io/js/commento.js', defer: true
]
,
apollo:
blogPost:
query: gpl`
query BlogPost($slug: String!)
blogPost(filter: slug: eq: $slug )
title
titleColor
hex
slug
author
keywords
_seoMetaTags
tag
attributes
content
_firstPublishedAt
banner
id
url
title
content
... on HeadingRecord
_modelApiKey
heading
... on SubHeadingRecord
_modelApiKey
subHeading
... on TextRecord
_modelApiKey
content
... on CodeRecord
_modelApiKey
codeBlock
... on ImageRecord
_modelApiKey
image
id
height
width
url
title
alt
... on VideoRecord
_modelApiKey
video
height
provider
providerUid
thumbnailUrl
title
url
width
`,
prefetch( route )
return
slug: route.params.slug
;
,
variables()
return
slug: this.$route.params.slug
;
如果有帮助,还有我的 nuxt.config.js:
const pkg = require('./package')
const webpack = require('webpack'); 从“节点获取”导入获取; 从'apollo-link'导入执行,makePromise; 从“apollo-link-http”导入 createHttpLink ; 从'graphql-tag'导入gql;
module.exports = 模式:'通用',
/*
** Headers of the page
*/
head:
title: pkg.name,
htmlAttrs:
lang: 'en'
,
meta: [
charset: 'utf-8' ,
name: 'viewport', content: 'width=device-width, initial-scale=1' ,
hid: 'description', name: 'description', content: pkg.description
],
link: [
rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' ,
rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css'
]
,
/*
** Customize the progress-bar color
*/
loading: color: '#fff' ,
/*
** Global CSS
*/
css: [
],
/*
** Plugins to load before mounting the App
*/
plugins: [
],
/*
** Nuxt.js modules
*/
modules: [
'@nuxtjs/style-resources',
'@nuxtjs/apollo',
'@nuxtjs/google-analytics'
],
/*
** @nuxtjs/google-analytics settings
*/
googleAnalytics:
id: 'UA-136517294-1'
,
/*
** @nuxtjs/style-resources settings
*/
styleResources:
scss: [
'./assets/css/*.scss'
]
,
/*
** Apollo setup for DatoCMS graphql queries
*/
apollo:
includeNodeModules: true,
clientConfigs:
default: '@/apollo/default.js'
,
/*
** Build configuration
*/
build:
postcss:
preset:
features:
customProperties: false
,
/*
** You can extend webpack config here
*/
extend(config, ctx)
,
/*
** Generate configuration
*/
generate:
routes: function(callback)
// Get the list of posts
const uri = 'https://graphql.datocms.com';
const link = new createHttpLink( uri: uri, fetch: fetch );
const operation =
query: gql`
allBlogPosts
id
slug
keywords
_seoMetaTags
tag
attributes
content
`,
context:
headers:
authorization: 'Bearer <my token>'
;
makePromise(execute(link, operation))
.then(data =>
// Build the routes from the posts
const postRoutes = data.data.allBlogPosts.map(item =>
return route: `/blog/$item.slug`, payload: keywords: item.keywords, seoData: item._seoMetaTags ;
);
// Register the routes
callback(null, postRoutes);
)
.catch(error => console.log(`received error $error`));
【问题讨论】:
仍会发出请求。见github.com/nuxt/rfcs/issues/22 @Aldarund 是的!这正是我遇到的。静态页面似乎可以生成,但头部代码正在重新触发数据查询或其他内容。不幸的是,它看起来并没有太多的解决方案。可能是时候使用 Gridsome 而不是 Nuxt 了。如果您创建一个答案,我会接受它。 【参考方案1】:如果您希望所有 api 请求都捆绑到应用程序中并且不再发出,那么 nuxt 目前不是这样工作的。它仍然会在应用程序的客户端导航上向 api 发出请求。
nuxt有制作全静态模式的计划,可以在这里追踪https://github.com/nuxt/rfcs/issues/22
【讨论】:
以上是关于如何使用 Apollo 在 Nuxt 生成的动态页面中正确填充页眉?的主要内容,如果未能解决你的问题,请参考以下文章
使用 nuxt-apollo 时如何使用 GraphQL 查询?
在 nuxt/vue 中来自 apollo 的数据发生变化后,子元素不更新道具
在 Apollo Nuxt 中,如何在方法中访问非默认客户端?
如何调试 nuxt-apollo 服务器端 graphql 请求