【问题标题】:Access nested nodes with GraphQL (Nuxt)使用 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 文件作为这个主题的答案;)顺便说一句,非常感谢你花时间阅读这些东西并帮助我。

标签: javascript vue.js graphql nuxt.js apollo


【解决方案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 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>

【讨论】:

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