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

Nuxt 3 SSR博客动态内容加载报错:content未定义

问题分析与解决方案

核心问题

你遇到的错误本质是异步请求未完成就尝试访问数据:

  • 调用postStore.getPostBySlug(slug)时没加await,导致后续直接取postStore.currentPost[0]时,接口还没返回数据,currentPost还是空数组,currentPost[0]就是undefined,自然读不到content。
  • 刷新页面能解决是因为刷新时服务端会重新执行数据请求,渲染时数据已经就绪;但页面跳转时是客户端导航,异步请求还在pending就开始渲染,触发错误。

修复步骤

1. 修正页面中的异步逻辑

把页面脚本里的异步调用改成正确的等待方式,确保数据返回后再赋值:

<template>
  <div class='grid grid-cols-6 gap-2'>
    <!-- 加加载状态避免空内容或错误 -->
    <div v-if="!post">加载中...</div>
    <div v-else>{{ post.content }}</div>
  </div>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router';
import { usePostStore } from '../../../../stores/post';
import { ref } from 'vue';

const postStore = usePostStore()
const route = useRoute()
const slug = route.params.slug
const post = ref(null)

// 必须await异步请求完成,再获取数据
await postStore.getPostBySlug(slug)
post.value = postStore.currentPost[0]

definePageMeta({
  layout: "posts",
})

// 处理post为null的情况,避免标题报错
useHead({
  title: post.value ? post.value.title : '博文详情'
})
</script>

2. 优化Pinia Store的错误处理

在getPostBySlug里加错误捕获,避免接口失败导致状态异常:

import { defineStore } from 'pinia';

export const usePostStore = defineStore('post-store', () => {
    const posts = ref([]);
    const pressReleases = ref([]);
    const news = ref([]);
    const currentPost = ref([]);

    // ...其他方法不变

    async function getPostBySlug(slug) {
        try {
            const { data, error } = await useAsyncGql({
                operation: 'getPostBySlug',
                variables: { slug: slug },
            });
            if (error) throw error
            currentPost.value = data._rawValue.post;
        } catch (err) {
            console.error('获取博文失败:', err)
            currentPost.value = [] // 出错时重置状态,避免旧数据干扰
        }
    }

    return {
        posts,
        currentPost,
        pressReleases,
        news,
        getPressReleases,
        getNews,
        getPostBySlug,
        getAllPosts,
    };
});

3. 适配Nuxt SSR的状态同步(推荐)

用Nuxt自带的useAsyncData处理数据获取,自动适配SSR和客户端导航的状态同步:

<template>
  <div class='grid grid-cols-6 gap-2'>
    <div v-if="pending">加载中...</div>
    <div v-else-if="error">加载失败,请重试</div>
    <div v-else>{{ post?.content }}</div>
  </div>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router';
import { usePostStore } from '../../../../stores/post';

const route = useRoute()
const slug = route.params.slug
const postStore = usePostStore()

// useAsyncData会自动缓存数据,避免重复请求,同时适配SSR
const { data: post, pending, error } = useAsyncData('post-' + slug, async () => {
  await postStore.getPostBySlug(slug)
  return postStore.currentPost[0]
})

definePageMeta({
  layout: "posts",
})

useHead({
  title: post.value ? post.value.title : '博文详情'
})
</script>

额外注意点

  • 模板里可以用可选链操作符{{ post?.content }},即使post为undefined也不会报错。
  • 始终保留加载状态和错误提示,提升用户体验。

内容的提问来源于stack exchange,提问作者Calvin Coleman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:55:27