使用 GraphQL (Nuxt) 访问嵌套节点

Posted

技术标签:

【中文标题】使用 GraphQL (Nuxt) 访问嵌套节点【英文标题】:Access nested nodes with GraphQL (Nuxt) 【发布时间】:2021-09-04 00:47:45 【问题描述】:

我在使用 Apollo、GraphQL 和 Nuxt 时遇到了一些问题。我不知道它是否与 Nuxt 或 vue 特别相关。

我正在尝试通过 WP-GraphQL 插件将 WordPress 用作无头 CMS。这是我的查询

WP-GraphQL interface

我基本上创建了一个 graphql 文件夹,里面有一个 posts.js 文件,其中包含我的查询

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"

这完全有道理,因为 author 是一个包含嵌套项的对象。所以根据我返回的内容和遵循 GraphQL API 结构,要显示帖子作者姓名,我认为我应该这样做:

<span> post.author.node.name </span>

这是我得到的错误,我不知道该怎么做才能访问我想要的: 无法读取未定义的属性“节点”。

【问题讨论】:

从错误消息中我们可以假设post.author 在这种情况下是undefined。您确定每个帖子甚至都有与之关联的作者吗?也许将您的 api 请求的结果打印到控制台以查看,或者如果您需要进一步的帮助,请将其添加到您的问题中。 显示更多代码/repo/sandbox with structure/details 是的,post.author 存在,我什至可以将它记录在 mount() 挂钩中。例如,如果我尝试记录 post.author[0].node.name,它将打印正确的作者姓名。问题似乎来自其他地方。我在 WordPress 后台写了 4 篇文章,是的,每篇文章都有相应的作者。我会尝试发布更多代码以便调试更容易 不要相信console.log(),它并不完全可靠,可以通过浏览器“用户友好”逻辑“神奇地”更新......是的,作者必须存在于 WP 帖子中......再次/仍然,显示代码/用法...或使用 react/gatsby/next :p 好吧!然后,它确实存在于 WP 中,但可能不在应用程序中(至少,当我尝试打印它时它还不存在)。如果它可以帮助调试,我刚刚发布了整个 index.vue 文件作为这个主题的答案;)顺便说一句,非常感谢你花时间阅读这些东西并帮助我。 【参考方案1】:

您的问题源于在加载数据之前读取数据。

根据您的 js 设置,您应该能够使用以下之一:

&lt;span&gt; post?.author.node.name &lt;/span&gt;

&lt;span&gt; post ? post.author.node.name : '' &lt;/span&gt;


根据 Vue Apollo 文档,这也可能是查询重复的问题

<script>
import  myQuery  from '~/graphql/posts'

export default 
  data() 
    return 
      posts: [], // initialization
    
  ,

  apollo: 
    posts: 
      prefetch: false, // to prevent s-s-r
      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>

【讨论】:

首先感谢您的回答!它似乎对我不起作用,您提出的建议都没有成功。我仍然有一个正在返回的“无法读取未定义的属性'节点'”错误 我假设还有其他事情发生,那么作者对 graphql 类型的内省呢?我根据您的另一条评论假设它是一个数组。 post.author[0].node.name

以上是关于使用 GraphQL (Nuxt) 访问嵌套节点的主要内容,如果未能解决你的问题,请参考以下文章

为啥将 Apollo 与 Nuxt 一起使用需要 graphql-tag?

动态 slug 未使用 graphql 和 nuxt 填充 url

Nuxt + GraphQL (Apollo) 上传文件

突变中的 GraphQL 嵌套节点 - 对象文字只能指定已知属性,并且类型中不存在“天”

使用 nuxt-apollo 时如何使用 GraphQL 查询?

如何处理数据加载器/GraphQL 嵌套查询中的并发 DbContext 访问?