主题
Headless WordPress 与 Nuxt 前端集成及附件处理
在现代前端开发中,将 WordPress 作为 Headless CMS 与 Nuxt 结合,是一种常见的技术方案。本文将系统讲解这种架构,并详细说明 文章中包含附件时的处理方法。
一、架构思路
1. WordPress 作为后端(Headless CMS)
- 仅负责 内容管理;
- 通过 REST API 或 GraphQL 提供数据;
- 不负责页面渲染。
2. Nuxt 作为前端(展示层)
- 渲染页面、优化 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 install2. 创建 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">
<NuxtLink :to="`/post/${post.id}`">{{ post.title.rendered }}</NuxtLink>
</div>
</div>
</template>
<script setup>
const posts = await useApi("posts", { per_page: 5 });
</script>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>
<script setup>
const route = useRoute();
const post = await useApi(`posts/${route.params.id}`);
</script>四、处理文章中的附件
WordPress 的附件是一种 post_type = attachment,可分为:
- 正文中插入的图片或文件
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>- 封面图 / featured_media 通过
featured_media字段获取:
js
let cover = null;
if (post.featured_media) {
cover = await useApi(`media/${post.featured_media}`);
}- 自定义字段(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>
<script setup>
const route = useRoute();
const post = await useApi(`posts/${route.params.id}`);
// 修复跨域资源路径(可选)
const fixedContent = post.content.rendered;
// 获取封面图
let cover = null;
if (post.featured_media) cover = await useApi(`media/${post.featured_media}`);
</script>五、推荐最佳实践
| 需求 | 推荐做法 |
|---|---|
| 一般文章(含图片) | 直接渲染 content.rendered |
| 有封面图 | 用 featured_media 获取附件详情 |
| 有文件附件 | 在 ACF 或自定义字段中存储文件信息 |
| 跨域资源 | HTML 中替换路径 + nginx 代理 /media |
| SEO 优化 | 使用同域名或 CDN 域名资源 |