Skip to content

获取文章列表

接口信息

  • 接口路径: /api/articles
  • 请求方法: GET
  • Content-Type: application/json
  • 是否需要认证: 否

请求参数

查询参数 (Query)

参数名类型必填默认值说明
pagenumber1页码(从1开始)
limitnumber4每页数量(最大20)
featuredbooleanfalse是否只获取推荐文章

请求示例

获取第一页文章

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
  }
}

响应字段说明

文章对象字段

字段名类型说明
idnumber文章 ID
titlestring文章标题
excerptstring文章摘要(前100字符)
datestring发布时间(ISO 8601)
categorystring分类名称
coverstring | null封面图片 URL
commentsnumber评论数(当前固定为0)
viewsnumber浏览量
slugstring文章别名(用于路由)

分页对象字段

字段名类型说明
pagenumber当前页码
limitnumber每页数量
totalnumber总记录数
pagesnumber总页数

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()
  }
})

注意事项

  1. 只返回已发布文章: 状态为 published 的文章
  2. 分页限制: 每页最大 20 条,超出会被限制
  3. 时间排序: 默认按创建时间倒序排列
  4. 评论数: 当前固定返回 0,待评论功能实现

相关接口