Nuxt

技术栈
前端框架
nuxtvuessrssg全栈前端

概览

Nuxt 技术栈概览

Nuxt 是 Vue 生态的全栈元框架,对标 React 的 Next.js,提供文件路由、SSR/SSG、自动导入、模块生态和 Nitro 服务端引擎,是 Vue 开发者构建生产应用的终极选择。

解决什么问题

  • 零配置 SSR:Vue SPA 无法做 SEO,Nuxt 开箱即用服务端渲染
  • 自动导入:components/、composables/、utils/ 下的文件无需手动 import
  • 文件路由pages/about.vue 自动生成 /about 路由
  • 全栈能力server/api/ 目录写 API,部署为一个 Node 服务

关键特性

  • Nitro 引擎:跨平台服务端引擎,部署 Node/Deno/Cloudflare/Netlify 等
  • Hybrid Rendering:每个路由独立配置 SSR/SSG/SWR/ISR
  • 模块生态:100+ 官方模块(PWA、SEO、Sitemap、Auth、Image...)
  • Nuxt DevTools:内置可视化调试面板,组件/状态/Pinia/网络请求一目了然
  • Layer:可复用 Nuxt 配置为 Layer,团队/社区共享
  • TypeScript 原生:零配置 .ts 支持

毕设场景

  • 全栈 Vue 毕设首选(Nuxt + Prisma + PostgreSQL)
  • SaaS 模板(Nuxt + Supabase + Stripe)
  • 内容网站/作品集(Nuxt Content + MDC 组件写 Markdown)
  • 部署到 Vercel/Netlify 免费,答辩演示方便

安装

Nuxt 安装指南

1. 环境准备

  • Node.js:>= 18.x(推荐 20 LTS,Nuxt 3 要求)
  • 包管理器:npm / pnpm(推荐)/ yarn / bun
  • IDE:VS Code + Volar + Nuxtr 插件
  • 浏览器:Chrome + Vue Devtools

2. 安装命令

创建项目

# 推荐:nuxi CLI
npx nuxi@latest init my-nuxt-app

# 或指定包管理器
npx nuxi@latest init my-nuxt-app --packageManager pnpm

# 交互式选择
# → Which modules would you like to add?
#   可选:@nuxt/ui (UI组件) / @nuxt/content (CMS) / @nuxtjs/i18n 等

cd my-nuxt-app
npm run dev
# → http://localhost:3000

模块安装示例

# Tailwind CSS(Nuxt UI 已内置)
npx nuxi module add tailwindcss

# 内容管理
npx nuxi module add content

# 图标
npx nuxi module add icon

项目结构

pages/           # 文件路由
  index.vue       # /
  about.vue       # /about
components/      # 自动导入
server/          # Nitro 服务端
  api/            # API 端点
nuxt.config.ts   # 配置文件

3. 常见安装问题

Q: nuxi 命令找不到?
A: 使用 npx nuxi@latest;或全局安装 npm i -g nuxi

Q: 端口冲突?
A: nuxt.config.tsdevServer: { port: 3001 }

Q: Nuxt 2 → Nuxt 3 区别?
A: 毕设一律用 Nuxt 3(Vue 3 + Composition API + Nitro)。Nuxt 2 已停止维护

示例

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 和前端一体

教程

Nuxt — Vue 全栈元框架

背景

Nuxt 是 Vue 生态的 Next.js 对标品,基于 Nitro 引擎提供 SSR/SSG/ISR、文件路由、自动导入和模块生态,是 Vue 开发者做毕设的全栈首选。

核心概念

1. 自动导入

Nuxt 3 自动导入 Vue API 和 components/composables/ 下的文件,无需手动 import:

<script setup lang="ts">
// 无需 import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count * 2)

// 自动导入 composables/useAuth.ts
const { user, login } = useAuth()
</script>

<template>
  <!-- 自动导入 components/MyButton.vue -->
  <MyButton @click="count++">点击: {{ count }}</MyButton>
</template>

2. 文件路由

pages/
  index.vue              → /
  about.vue              → /about
  blog/
    [slug].vue           → /blog/:slug
server/
  api/
    posts.ts             → /api/posts
    posts/[id].ts        → /api/posts/:id

3. useFetch / useAsyncData

<script setup>
// 服务端获取数据,客户端水合
const { data: posts, pending, error, refresh } = await useFetch('/api/posts')

// 带参数的
const { data: post } = await useAsyncData('post', () =>
  $fetch(`/api/posts/${route.params.id}`)
)
</script>

4. Nitro 引擎

Nuxt 底层服务端是 Nitro,支持部署到:

平台 方式
Node.js node .output/server/index.mjs
Vercel 零配置
Netlify 零配置
Cloudflare Workers 零配置
Deno 实验性

5. Nuxt 模块

# 一行命令安装模块
npx nuxi module add content    # 文件型 CMS
npx nuxi module add tailwindcss
npx nuxi module add icon
npx nuxi module add pwa
npx nuxi module add seo

分步操作

npx nuxi@latest init grad-project
cd grad-project
npm run dev
# → http://localhost:3000

思考题

  1. useFetch$fetch 的区别是什么?
  2. Nuxt 的 server/pages/ 分别对应什么职责?
  3. Nuxt Layer 是什么?如何在多项目间复用配置?

毕设场景

  • 全栈 Vue 毕设首选
  • 内容网站/文档(Nuxt Content)
  • SaaS MVP(Nuxt + Supabase + Stripe)