Hello World - 全栈代办+API

知识库
知识库文档
/tech-stacks/nuxt/examples/Hello World - 全栈代办+API.md

文档

Nuxt 全栈代办事项 + API

目标

展示 Nuxt 全栈能力:前端代办 UI + server/api/ 后端接口 + useFetch 调用。

完整代码

server/api/todos.ts

// Nuxt Nitro API — 内存存储示例
let todos: { id: number; text: string; done: boolean }[] = [
  { id: 1, text: '学习 Nuxt 3', done: true },
  { id: 2, text: '完成毕设', done: false },
]
let nextId = 3

export default defineEventHandler(async (event) => {
  const method = event.method

  // GET /api/todos
  if (method === 'GET') {
    return todos
  }

  // POST /api/todos
  if (method === 'POST') {
    const body = await readBody(event)
    const todo = { id: nextId++, text: body.text, done: false }
    todos.push(todo)
    return todo
  }

  // DELETE /api/todos?id=1
  if (method === 'DELETE') {
    const id = Number(getQuery(event).id)
    todos = todos.filter(t => t.id !== id)
    return { success: true }
  }

  throw createError({ statusCode: 405 })
})

pages/index.vue

<script setup lang="ts">
const newTodo = ref('')

// useFetch 在服务端和客户端都能工作
const { data: todos, refresh } = await useFetch('/api/todos')

const { data: serverInfo } = await useFetch('/api/info')

async function addTodo() {
  const text = newTodo.value.trim()
  if (!text) return
  await $fetch('/api/todos', { method: 'POST', body: { text } })
  newTodo.value = ''
  refresh()
}

async function removeTodo(id: number) {
  await $fetch(`/api/todos?id=${id}`, { method: 'DELETE' })
  refresh()
}

async function toggleTodo(todo: any) {
  // 简化 toggle,实际应加 PATCH
  todo.done = !todo.done
}
</script>

<template>
  <div class="container">
    <h1>🏔️ Nuxt 全栈代办</h1>

    <!-- 服务端信息 -->
    <div class="server-info">
      <span>🖥️ 服务端信息: {{ serverInfo }}</span>
    </div>

    <!-- 输入 -->
    <form @submit.prevent="addTodo" class="input-group">
      <input v-model="newTodo" placeholder="输入新任务..." class="todo-input" />
      <button type="submit">添加</button>
    </form>

    <!-- 列表 -->
    <ul class="todo-list">
      <li v-for="todo in todos" :key="todo.id">
        <span @click="toggleTodo(todo)" style="cursor:pointer">
          {{ todo.done ? '✅' : '⬜' }}
          <span :class="{ done: todo.done }">{{ todo.text }}</span>
        </span>
        <button @click="removeTodo(todo.id)" class="del-btn">🗑️</button>
      </li>
    </ul>
  </div>
</template>

<style scoped>
.container { max-width: 480px; margin: 2rem auto; font-family: system-ui; }
h1 { color: #00dc82; }
.server-info { background: #f0fdf4; padding: 8px 12px; border-radius: 8px; font-size: 0.85rem; margin-bottom: 1rem; }
.input-group { display: flex; gap: 8px; margin-bottom: 1rem; }
.todo-input { flex: 1; padding: 8px 12px; border: 2px solid #e2e8f0; border-radius: 8px; }
button { padding: 8px 16px; background: #00dc82; color: white; border: none; border-radius: 8px; cursor: pointer; }
.todo-list { list-style: none; padding: 0; }
.todo-list li { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f1f5f9; }
.done { text-decoration: line-through; color: #94a3b8; }
.del-btn { background: none; border: none; cursor: pointer; }
</style>

server/api/info.ts

export default defineEventHandler(() => ({
  runtime: 'Nitro',
  timestamp: new Date().toISOString(),
  node: process.version,
}))

运行

npm run dev
# → http://localhost:3000

预期输出

  • 服务端信息显示在顶部(SSR 渲染)
  • 代办列表从 /api/todos 获取
  • 添加/删除实时刷新,API 和前端一体

信息

路径
/tech-stacks/nuxt/examples/Hello World - 全栈代办+API.md
更新时间
2026/5/30