问题描述
我在使用 Apollo、GraphQL 和 Nuxt 时遇到了一些问题。我不知道它是否与 Nuxt 或 vue 特别相关。
我正在尝试通过 WP-GraphQL 插件将 wordpress 用作无头 CMS。这是我的查询
我基本上创建了一个带有 posts.js 文件的 graphql 文件夹,其中包含我的查询
import gql from 'graphql-tag'
export const myQuery = gql`
query myQuery {
posts {
nodes {
id
title
date
slug
author {
node {
name
}
}
featuredImage {
node {
uri
sourceUrl
srcSet
}
}
}
}
}
`
然后,我需要做的就是在模板中打印我的数据。首先是脚本部分。
<script>
import { myQuery } from '~/graphql/posts'
export default {
data() {
return {
posts: [],}
},apollo: {
posts: {
prefetch: true,query: myQuery,},watch: {
async $route() {
await this.$nuxt.refresh()
window.scrollTo(0,0)
},transition: 'home',async mounted() {
this.posts = await this.$apollo.query({ query: myQuery })
this.posts = this.posts.data.posts.nodes
this.loading = false
}
</script>
然后是模板:
<template>
<section class="featured-projects">
<div class="featured-projects__wrapper">
<article v-for="post in posts" :key="post.id">
<p>{{ post.id }}</p>
<h2>{{ post.title }}</h2>
<span>{{ post.date }}</span>
</article>
</div>
</section>
</section>
</template>
一切正常!
现在,我也想打印帖子作者姓名。我第一次尝试这个:
<span>{{ post.author }}</span>
这实际上打印了这个:
{
"node": {
"name": "max max","__typename": "User"
},"__typename": "NodeWithAuthorToUserConnectionEdge"
}
这完全有道理,因为作者是一个包含嵌套项目的对象。所以根据我返回的内容和遵循 GraphQL API 结构,要显示帖子作者姓名,我认为我应该做这样的事情:
<span>{{ post.author.node.name }}</span>
这是我得到的错误,我不知道如何访问我想要的: 无法读取未定义的属性“节点”。
解决方法
您的问题是由于在加载数据之前读取数据引起的。
根据您的 js 设置,您应该能够使用以下之一:
<span>{{ post?.author.node.name }}</span>
或 <span>{{ post ? post.author.node.name : '' }}</span>
根据 Vue Apollo 文档,它也可能是查询重复的问题
<script>
import { myQuery } from '~/graphql/posts'
export default {
data() {
return {
posts: [],// initialization
}
},apollo: {
posts: {
prefetch: false,// to prevent SSR
query: myQuery,update: data => {
console.log('overwrite posts with new data',data.posts)
return data.posts
}
},}
}
</script>
此外,似乎有些情况下作者有多个条目(也许是共同作者?),我会尝试将作者渲染更新为以下内容:
<template>
<section class="featured-projects">
<div class="featured-projects__wrapper">
<article v-for="post in posts" :key="post.id">
<p>{{ post.id }}</p>
<div v-if="Array.isArray(post.author)">
first author is: {{ post.author[0].node.name }}
</div>
<div v-else-if="post.author">
author is: {{ post.author.node.name }}
</div>
<div v-else="post.author">
no author
</div>
</article>
</div>
</section>
</section>
</template>