文章 文章 posts

Headless WordPress 与 Nuxt 前端集成及附件处理

在现代前端开发中,将 WordPress 作为 Headless CMS 与 Nuxt 结合,是一种常见的技术方案。本文将系统讲解这种架构,并详细说明 文章中包含附件时的处理方法。

一、架构思路

1. WordPress 作为后端(Headless CMS)

  • 仅负责 内容管理;
  • 通过 REST API 或 GraphQL 提供数据;
  • 不负责页面渲染。

2. Nuxt 作为前端(展示层)

  • 渲染页面、输出 HTML 内容、优化 SEO、处理前端交互;
  • 从 WordPress 获取数据;
  • 支持 SSR(服务器端渲染) 或 SSG(静态生成);
  • 可部署到 Vercel、Netlify、Cloudflare Pages 等平台。

二、WordPress 配置(后端)

1. 开启 REST API

WordPress 默认启用 REST API:

代码

[https://your-domain.com/wp-json/wp/v2/posts](https://your-domain.com/wp-json/wp/v2/posts)


### 2. 常用数据接口
| 内容类型 | REST API 路径 | 示例 |
|-----------|----------------|------|
| 所有文章 | `/wp-json/wp/v2/posts` | `/wp-json/wp/v2/posts?page=1&per_page=5` |
| 单篇文章 | `/wp-json/wp/v2/posts/:id` | `/wp-json/wp/v2/posts/123` |
| 分类 | `/wp-json/wp/v2/categories` | `/wp-json/wp/v2/categories?slug=news` |
| 页面 | `/wp-json/wp/v2/pages` | `/wp-json/wp/v2/pages?slug=about` |
| 媒体(图片/附件) | `/wp-json/wp/v2/media` | `/wp-json/wp/v2/media/45` |

> ⚠️ 如果跨域访问 Nuxt 前端,需要在 WordPress 配置 CORS 或安装相关插件。

## 三、Nuxt 前端实现

假设使用 **Nuxt 4/3**。

### 1. 安装依赖
```
bash
npx nuxi init my-blog
cd my-blog
npm install

2. 创建 API composable

文件:composables/useApi.js

代码
js
export const useApi = async (endpoint, params = {}) => {
  const baseURL = "https://your-wordpress-site.com/wp-json/wp/v2";
  const url = new URL(`${baseURL}/${endpoint}`);
  Object.entries(params).forEach(([key, value]) =>
    url.searchParams.append(key, value)
  );
  const { data, error } = await useFetch(url.toString());
  if (error.value) throw new Error(error.value);
  return data.value;
};

3. 获取文章列表

文件:pages/index.vue

代码
vue
<template>
  <div>
    <h1>最新文章</h1>
    <div v-for="post in posts" :key="post.id">
      <div class="not-prose my-6 rounded-lg border border-blue-100 bg-blue-50 p-4 text-sm text-blue-800">NuxtLink 组件内容已保留为静态页面,交互部分将继续迁移。</div>
    </div>
  </div>
</template>



4. 获取文章详情

文件:pages/post/[id].vue

代码
vue
<template>
  <article v-if="post">
    <h1 v-html="post.title.rendered"></h1>
    <div v-html="post.content.rendered"></div>
  </article>
</template>



四、处理文章中的附件

WordPress 的附件是一种 post_type = attachment,可分为:

  1. 正文中插入的图片或文件
代码
html
<p><img src="https://example.com/wp-content/uploads/photo.jpg" /></p>
<p><a href="https://example.com/wp-content/uploads/report.pdf">下载报告</a></p>

  1. 封面图 / featured_media 通过 featured_media 字段获取:
代码
js
let cover = null;
if (post.featured_media) {
  cover = await useApi(`media/${post.featured_media}`);
}

  1. 自定义字段(ACF 或插件)上传的附件
代码
json
{
  "acf": {
    "attachments": [
      { "id": 231, "url": "https://.../file1.pdf" },
      { "id": 232, "url": "https://.../file2.docx" }
    ]
  }
}

Nuxt 前端处理示例

代码
vue
<template>
  <article>
    <h1 v-html="post.title.rendered"></h1>
    <img v-if="cover" :src="cover.source_url" :alt="cover.title.rendered" />
    <div v-html="fixedContent"></div>

    <ul v-if="post.acf?.attachments">
      <li v-for="f in post.acf.attachments" :key="f.id">
        <a :href="f.url" target="_blank"
          >下载 {{ f.title || f.url.split("/").pop() }}</a
        >
      </li>
    </ul>
  </article>
</template>


五、推荐最佳实践

需求 推荐做法
一般文章(含图片) 直接渲染 content.rendered
有封面图 用 featured_media 获取附件详情
有文件附件 在 ACF 或自定义字段中存储文件信息
跨域资源 HTML 中替换路径 + nginx 代理 /media
SEO 优化 使用同域名或 CDN 域名资源

六、参考资料