You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt.js+GraphQL对接Strapi无法访问文章title字段问题

Nuxt+GraphQL+Strapi项目中无法访问article.data.attributes.title的问题解决

问题

无法访问article.data.attributes.title字段,但可访问article.data.attributes,报错信息:

undefined is not an object (evaluating '_vm.article.data.attributes.title')

临时修改代码后可正常显示,但刷新页面错误再次出现。

相关代码

Vue组件代码:

<template>
  <div class="root-container">
    <Header />

    <main>
      <h1
        v-html="$md.render(String(article.data.attributes.title))"
        class="article-title"
      ></h1>
    </main>

    <Footer />
  </div>
</template>

<style scoped>
@import url(../../css/components/article.css);
</style>

<script>
import singleArticleQuery from "~/apollo/queries/articles/article";
import readingTime from "reading-time";
import date from "date_formating";

export default {
  methods: {
    readingTimeText(text) {
      return readingTime(`${text}`);
    },
    dateFormating(articleDate) {
      return date
        .PreDateFormate(`${articleDate}`, "DD-MM-YYYY")
        .replaceAll("-", "/");
    },
    add() {
      if (process.client) {
        return window.location.host.includes("localhost")
          ? "http://localhost:1337"
          : "";
      }
    },
  },
  data() {
    return {
      article: {
        data: [],
      },
    };
  },
  apollo: {
    article: {
      prefetch: true,
      query: singleArticleQuery,
      variables() {
        return {
          slug: this.$route.params.slug.substring(
            this.$route.params.slug.lastIndexOf("/") + 1
          ),
        };
      },
    },
  },
};
</script>

GraphQL查询:

query singleArticleQuery($slug: String!) {
  article(slug: $slug) {
    data {
      id
      attributes {
        title
        content
        image {
          data {
            attributes {
              url
            }
          }
        }
        slug
        date
        author
      }
    }
  }
}

API响应:

{ "data": { "id": "5", "attributes": { "title": "Pas d’annulation des « Loyers Covid » : fin de partie ? Portée et analyse des Arrêts du 30 juin 2022", "content": "Par trois arrêts du 30 juin 2022 (n°21-20190 ; 21.20127 et 21.19889) la 3ème Chambre de la Cour de Cassation a rejeté les trois principaux moyens développés par les locataires pour s'opposer au paiement des loyers des commerces considérés comme « non essentiels », en dépit de la fermeture ordonnée par les pouvoirs publics.\n\nCes décisions, si elles sont compréhensibles d'un point de vue économique (45% des commerces de détails fermés, 3 milliards de dette locative selon une note du ministère de l'économie), ne sont pas dénuées de critiques au plan du droit.\n\n## 1. Réponses apportées aux contestations opposées à la demande de paiement des loyers\n\nRappelons qu'en l'absence de dispositions spécifiques aux baux commerciaux, les locataires ont dû rechercher les ressources offertes par le droit commun du contrat de louage d'ouvrage :\n\n- La perte de la chose louée,\n- L'obligation de délivrance du bailleur avec pour corolaire l'exception d'inexécution\n- La force majeure\n\nLes juges du fond étaient partagés mais admettaient assez largement la perte de la chose louée au sens fonctionnel ou économique. La Cour de Cassation a entendu uniformiser la jurisprudence.\n\n### 1 / La perte de la chose louée (article 1722 du code civil)\n\nPour écarter la perte de la chose louée, la Cour de Cassation retient que l'interdiction d'accueil au public était « <em><strong>temporaire</strong></em> » et « <em><strong>sans lien direct avec la destination contractuelle du local</strong></em> ».\n\nCette motivation ne peut que surprendre dès lors que :\n\n- C'est bien la destination des lieux qui a déterminé l'application de la mesure générale d'ouverture au public ;\n- Le caractère limité de la perte n'a jamais fait obstacle à l'application de l'article 1722 selon une jurisprudence ancienne. Ainsi, dans un arrêt du 29 novembre 1965, la première chambre civile de la Cour de Cassation a rejeté le pourvoi formé par le bailleur contre la décision qui avait jugé que le preneur dans l'impossibilité́ d'utiliser la chose louée « \"<em>pendant une certaine période</em> » pouvait, sur le fondement de l'article 1722 du code civil, exiger du bailleur le remboursement d'une partie du prix de la location (Bull. civ. I, n° 655).\n\nDe même, la Cour de Cassation a jugé que l'arrêt, par cas fortuit, de la fourniture d'eau constitue une perte partielle justifiant une diminution du prix (Cass. 3e civ., 17 juin 1980 : Bull. civ. 1980, III, n° 116)\n\n### 2/ L'obligation de délivrance (article 1719 du code civil)\n\nLa Cour de Cassation rejette l'argument au motif que l'impossibilité d'exploiter <strong>n'était pas le fait du bailleur</strong> mais celui du législateur, privant ainsi les preneurs de la possibilité d'invoquer le principe d'exception d'inexécution.\n\nOr, nombre de décisions ont pourtant admis que le bailleur est garant de l'usage paisible des lieux tout au long du bail conformément aux normes en vigueur, sauf stipulation expresse contraire du bail.\n\n### 3/ La force majeure (article 1218 du Code Civil)\n\nLa Haute Cour, écarte ce fondement. On ne s'y attardera pas car ce moyen s'avérait en tout état de cause moins efficace pour le preneur qui ne pouvait lui permettre que d'obtenir un report de la dette de loyers et non pas une annulation pure et simple au regard de l'impossibilité provisoire d'exploiter.\n\n## 2. Est-ce à dire que le débat judiciaire est définitivement clos ?\n\nProbablement pas. Il faut tout d'abord relativiser la portée ces arrêts étant rappelé que les décisions ne portent que sur le <strong>premier confinement</strong> , la Haute Cour ne s'étant pas encore prononcée sur les autres vagues.\n\nEn outre, il n'est pas exclu que certaines juridictions puissent résister à la position exprimée par la Cour de Cassation dans des litiges dont les circonstances ne sont pas identiques.\n\nDans les affaires soumises à la censure de la Cour de Cassation, la bonne ou mauvaise foi des parties a en effet été relevée lorsque le bailleur avait offert de reporter le paiement du loyer et avait fait preuve de patience avant d'assigner.\n\nLa cour d'appel de Paris a ainsi rappelé que « <em>Les contrats devant être exécutés de bonne foi selon l'article 1134 devenu 1104 du code civil, les parties sont tenues, en cas de circonstances exceptionnelles et graves de vérifier si ces circonstances ne rendent pas nécessaire une adaptation des modalités d'exécution de leurs obligations respectives</em> ».\n\n<strong>Il ne faut pas enfin perdre de vue que tous les moyens à la disposition des preneurs n'ont pas encore été tranchés.</strong>\n\nAinsi en est-il :\n\n- Des cas où les baux contiennent une disposition prévoyant la suspension des loyers en cas de circonstances graves et légitimes ;\n- De l'imprévision pour les baux conclus antérieurement à la réforme du droit des obligations de 2016 ;\n\n- De l'article 1131 du Code Civil pour les baux antérieurs à la réforme de 2016 comme fondement à une action en diminutiondu prix du loyer au regard de l'absence de cause à l'obligation de paiement.\n\nCes moyens pourraient permettre d'envisager si ce n'est l'annulation totale de la dette pendant la période d'inexploitation, au moins une réduction de loyers.", "image": { "data": { "attributes": { "url": "/uploads/11062b_49bd140ff6034d019057a7dddc081e2c_mv2_jpg_e83c5ff9c0.webp", "__typename": "UploadFile" }, "__typename": "UploadFileEntity" }, "__typename": "UploadFileEntityResponse" }, "slug": "pas-d-annulation-des-loyers-covid-fin-de-partie-portee-et-analyse-des-arrets-du-30-juin-2022", "date": "2022-12-01", "author": "Johanne Zakine", "__typename": "Article" }, "__typename": "ArticleEntity" }, "__typename": "ArticleEntityResponse" }

原因分析

页面初始渲染时,Apollo尚未完成GraphQL请求,此时article使用的是data中定义的初始值{ data: [] }——article.data是数组而非对象,没有attributes属性,访问article.data.attributes.title自然会抛出undefined错误。热重载时数据已加载完成,所以临时正常;刷新后回到初始状态,请求未完成就再次报错。

解决方案

1. 使用可选链操作符(推荐)

在模板中通过?.安全访问深层属性,避免未定义报错:

<h1 v-html="$md.render(String(article.data?.attributes?.title))" class="article-title"></h1>

2. 匹配响应格式初始化数据

将data中的article初始值改为与API响应一致的结构,避免类型不匹配:

data() {
  return {
    article: {
      data: {
        attributes: {}
      }
    },
  };
}

3. 添加加载状态判断

利用Apollo的查询加载状态,在数据未加载完成时显示占位内容:

<main>
  <div v-if="$apollo.queries.article.loading">加载中...</div>
  <h1 v-else v-html="$md.render(String(article.data.attributes.title))" class="article-title"></h1>
</main>

4. 使用asyncData预加载数据(页面组件适用)

如果是页面组件,可通过asyncData在页面渲染前完成数据查询:

async asyncData({ $apollo, params }) {
  const slug = params.slug.substring(params.slug.lastIndexOf("/") + 1);
  const { data } = await $apollo.query({
    query: singleArticleQuery,
    variables: { slug }
  });
  return { article: data.article };
}

内容的提问来源于stack exchange,提问作者MH info

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:17:32