获取文章列表
接口信息
- 接口路径:
/api/articles - 请求方法:
GET - Content-Type:
application/json - 是否需要认证: 否
请求参数
查询参数 (Query)
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | number | 否 | 1 | 页码(从1开始) |
| limit | number | 否 | 4 | 每页数量(最大20) |
| featured | boolean | 否 | false | 是否只获取推荐文章 |
请求示例
获取第一页文章
bash
curl -X GET "http://localhost:3000/api/articles?page=1&limit=4"获取推荐文章
bash
curl -X GET "http://localhost:3000/api/articles?featured=true&limit=6"获取第2页文章,每页10条
bash
curl -X GET "http://localhost:3000/api/articles?page=2&limit=10"响应示例
成功响应
json
{
"success": true,
"data": [
{
"id": 1,
"title": "Nuxt 4 全栈开发指南",
"excerpt": "本文详细介绍如何使用 Nuxt 4 构建现代化的全栈应用...",
"date": "2025-01-20T00:00:00.000Z",
"category": "技术分享",
"cover": "https://example.com/covers/article1.jpg",
"comments": 5,
"views": 1200,
"slug": "nuxt-4-quan-zhan-kai-fa-zhi-nan-1"
},
{
"id": 2,
"title": "Vue 3 组合式 API 最佳实践",
"excerpt": "深入理解 Vue 3 Composition API 的使用技巧...",
"date": "2025-01-18T00:00:00.000Z",
"category": "前端开发",
"cover": "https://example.com/covers/article2.jpg",
"comments": 3,
"views": 850,
"slug": "vue-3-zu-he-shi-api-zui-jia-shi-jian-2"
}
],
"pagination": {
"page": 1,
"limit": 4,
"total": 50,
"pages": 13
}
}响应字段说明
文章对象字段
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | number | 文章 ID |
| title | string | 文章标题 |
| excerpt | string | 文章摘要(前100字符) |
| date | string | 发布时间(ISO 8601) |
| category | string | 分类名称 |
| cover | string | null | 封面图片 URL |
| comments | number | 评论数(当前固定为0) |
| views | number | 浏览量 |
| slug | string | 文章别名(用于路由) |
分页对象字段
| 字段名 | 类型 | 说明 |
|---|---|---|
| page | number | 当前页码 |
| limit | number | 每页数量 |
| total | number | 总记录数 |
| pages | number | 总页数 |
Slug 生成规则
Slug 由标题和 ID 组合而成,格式为:{标题拼音}-{id}
示例:
- 标题: "Nuxt 4 全栈开发指南", ID: 1
- Slug: "nuxt-4-quan-zhan-kai-fa-zhi-nan-1"
前端集成示例
使用 useFetch
vue
<script setup>
const route = useRoute()
const page = computed(() => route.query.page || 1)
const limit = computed(() => route.query.limit || 4)
const { data, pending, error, refresh } = await useFetch('/api/articles', {
query: { page, limit }
})
</script>
<template>
<div>
<div v-if="pending">加载中...</div>
<div v-else-if="error">加载失败</div>
<div v-else>
<!-- 文章列表 -->
<article v-for="article in data.value.data" :key="article.id">
<img :src="article.cover" :alt="article.title" />
<h3>{{ article.title }}</h3>
<p>{{ article.excerpt }}</p>
<NuxtLink :to="`/articles/${article.slug}`">阅读更多</NuxtLink>
</article>
<!-- 分页 -->
<div class="pagination">
<NuxtLink
v-if="data.pagination.page > 1"
:to="`?page=${data.pagination.page - 1}`"
>
上一页
</NuxtLink>
<span>第 {{ data.pagination.page }} / {{ data.pagination.pages }} 页</span>
<NuxtLink
v-if="data.pagination.page < data.pagination.pages"
:to="`?page=${data.pagination.page + 1}`"
>
下一页
</NuxtLink>
</div>
</div>
</div>
</template>使用组合式函数
typescript
// app/composables/useArticles.ts
export function useArticles() {
const articles = ref([])
const pagination = ref({
page: 1,
limit: 4,
total: 0,
pages: 0
})
const loading = ref(false)
const error = ref(null)
const fetchArticles = async (params = {}) => {
loading.value = true
error.value = null
try {
const response = await fetch(`/api/articles?${new URLSearchParams(params)}`)
const result = await response.json()
if (result.success) {
articles.value = result.data
pagination.value = result.pagination
} else {
throw new Error(result.message)
}
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
}
const loadPage = (page: number) => {
fetchArticles({ page, limit: pagination.value.limit })
}
return {
articles,
pagination,
loading,
error,
fetchArticles,
loadPage
}
}使用场景
1. 首页文章列表
javascript
const { data } = await useFetch('/api/articles', {
query: { featured: true, limit: 4 }
})2. 文章分类页
javascript
const { data } = await useFetch('/api/articles', {
query: { page, limit: 10 }
})3. 无限滚动加载
javascript
const { articles, pagination, fetchArticles } = useArticles()
const loadMore = async () => {
if (pagination.value.page < pagination.value.pages) {
await fetchArticles({ page: pagination.value.page + 1 })
// 合并数据
}
}
// 监听滚动事件
window.addEventListener('scroll', () => {
if (isBottom() && !loading.value) {
loadMore()
}
})注意事项
- 只返回已发布文章: 状态为
published的文章 - 分页限制: 每页最大 20 条,超出会被限制
- 时间排序: 默认按创建时间倒序排列
- 评论数: 当前固定返回 0,待评论功能实现