Nuxt全栈开发技能 nuxt

本技能提供基于 Vue.js 的 Nuxt 3 全栈应用开发专家指导,涵盖服务器端渲染、静态站点生成、API 路由构建、自动导入、模块配置和部署优化。适用于构建现代化、高性能的 Web 应用,支持混合渲染模式,并集成 Nitro 服务器引擎。关键词:Nuxt 3,全栈开发,Vue.js,服务器端渲染,SSR,静态站点生成,Nitro 服务器,混合渲染,TypeScript,前端框架。

前端开发 0 次安装 0 次浏览 更新于 2/26/2026

name: nuxt description: Nuxt 3 模式,包括 Nitro 服务器、自动导入、模块、混合渲染和全栈开发。 allowed-tools: Read, Write, Edit, Bash, Glob, Grep

Nuxt 技能

为使用 Nuxt 3 构建全栈应用程序提供专家级协助。

能力

  • 使用 TypeScript 配置 Nuxt 3 项目
  • 实现混合渲染(SSR、SSG、ISR、SPA)
  • 构建 Nitro 服务器路由和中间件
  • 使用自动导入创建组合式函数
  • 设置 Nuxt 模块和插件
  • 为各种平台配置部署

使用场景

在以下情况下调用此技能:

  • 创建 Nuxt 3 全栈应用程序
  • 实现服务器端渲染
  • 使用 Nitro 构建 API 路由
  • 配置渲染模式
  • 部署 Nuxt 应用程序

输入参数

参数 类型 必填 描述
projectType string 项目类型:全栈、静态、单页应用
rendering string 渲染模式:服务端渲染、静态生成、增量静态再生、单页应用
modules array 要包含的 Nuxt 模块
features array 功能:认证、国际化、渐进式网页应用等

配置示例

{
  "projectType": "fullstack",
  "rendering": "ssr",
  "modules": ["@nuxtjs/tailwindcss", "@pinia/nuxt", "@vueuse/nuxt"],
  "features": ["auth", "api"]
}

项目结构

nuxt-app/
├── .nuxt/                  # 构建目录
├── assets/                 # 未编译资源
├── components/             # 自动导入的组件
│   ├── base/
│   │   └── Button.vue     # <BaseButton />
│   └── TheHeader.vue      # <TheHeader />
├── composables/            # 自动导入的组合式函数
│   ├── useAuth.ts
│   └── useFetch.ts
├── layouts/                # 页面布局
│   ├── default.vue
│   └── auth.vue
├── middleware/             # 路由中间件
│   └── auth.ts
├── pages/                  # 基于文件的路由
│   ├── index.vue          # /
│   ├── about.vue          # /about
│   └── users/
│       ├── index.vue      # /users
│       └── [id].vue       # /users/:id
├── plugins/                # Vue 插件
│   └── api.ts
├── public/                 # 静态文件
├── server/                 # Nitro 服务器
│   ├── api/
│   │   └── users/
│   │       ├── index.ts   # /api/users
│   │       └── [id].ts    # /api/users/:id
│   ├── middleware/
│   │   └── auth.ts
│   └── utils/
│       └── db.ts
├── stores/                 # Pinia 状态管理
│   └── user.ts
├── nuxt.config.ts
└── app.vue

配置

// nuxt.config.ts
export default defineNuxtConfig({
  devtools: { enabled: true },

  modules: [
    '@nuxtjs/tailwindcss',
    '@pinia/nuxt',
    '@vueuse/nuxt',
  ],

  runtimeConfig: {
    // 仅服务器端
    databaseUrl: process.env.DATABASE_URL,
    jwtSecret: process.env.JWT_SECRET,

    // 客户端可访问
    public: {
      apiBase: process.env.API_BASE || '/api',
    },
  },

  routeRules: {
    '/': { prerender: true },
    '/api/**': { cors: true },
    '/dashboard/**': { ssr: false },
    '/blog/**': { isr: 3600 },
  },

  nitro: {
    preset: 'vercel',
  },
});

服务器 API 路由

// server/api/users/index.ts
export default defineEventHandler(async (event) => {
  const method = event.method;

  if (method === 'GET') {
    const query = getQuery(event);
    return await db.user.findMany({
      where: query.search
        ? { name: { contains: query.search as string } }
        : undefined,
    });
  }

  if (method === 'POST') {
    const body = await readBody(event);
    return await db.user.create({ data: body });
  }

  throw createError({ statusCode: 405, message: 'Method not allowed' });
});

// server/api/users/[id].ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id');
  const method = event.method;

  if (method === 'GET') {
    const user = await db.user.findUnique({ where: { id } });
    if (!user) {
      throw createError({ statusCode: 404, message: 'User not found' });
    }
    return user;
  }

  if (method === 'PUT') {
    const body = await readBody(event);
    return await db.user.update({ where: { id }, data: body });
  }

  if (method === 'DELETE') {
    await db.user.delete({ where: { id } });
    return { success: true };
  }
});

服务器中间件

// server/middleware/auth.ts
export default defineEventHandler(async (event) => {
  const protectedPaths = ['/api/users', '/api/posts'];
  const path = event.path;

  if (protectedPaths.some((p) => path.startsWith(p))) {
    const token = getHeader(event, 'authorization')?.replace('Bearer ', '');

    if (!token) {
      throw createError({ statusCode: 401, message: 'Unauthorized' });
    }

    try {
      const user = await verifyToken(token);
      event.context.user = user;
    } catch {
      throw createError({ statusCode: 401, message: 'Invalid token' });
    }
  }
});

页面和布局

<!-- pages/users/[id].vue -->
<script setup lang="ts">
const route = useRoute();
const { data: user, pending, error } = await useFetch(
  `/api/users/${route.params.id}`
);

useHead({
  title: () => user.value?.name ?? 'User',
});

definePageMeta({
  layout: 'default',
  middleware: 'auth',
});
</script>

<template>
  <div>
    <div v-if="pending">加载中...</div>
    <div v-else-if="error">{{ error.message }}</div>
    <div v-else>
      <h1>{{ user.name }}</h1>
      <p>{{ user.email }}</p>
    </div>
  </div>
</template>

<!-- layouts/default.vue -->
<template>
  <div class="min-h-screen">
    <TheHeader />
    <main class="container mx-auto px-4 py-8">
      <slot />
    </main>
    <TheFooter />
  </div>
</template>

组合式函数

// composables/useAuth.ts
export const useAuth = () => {
  const user = useState<User | null>('user', () => null);
  const token = useCookie('auth-token');

  const isAuthenticated = computed(() => !!user.value);

  async function login(email: string, password: string) {
    const { data } = await useFetch('/api/auth/login', {
      method: 'POST',
      body: { email, password },
    });

    if (data.value) {
      user.value = data.value.user;
      token.value = data.value.token;
    }
  }

  async function logout() {
    user.value = null;
    token.value = null;
    await navigateTo('/login');
  }

  async function fetchUser() {
    if (!token.value) return;

    const { data } = await useFetch('/api/auth/me', {
      headers: { Authorization: `Bearer ${token.value}` },
    });

    user.value = data.value;
  }

  return {
    user: readonly(user),
    isAuthenticated,
    login,
    logout,
    fetchUser,
  };
};

中间件

// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const { isAuthenticated } = useAuth();

  if (!isAuthenticated.value) {
    return navigateTo({
      path: '/login',
      query: { redirect: to.fullPath },
    });
  }
});

// middleware/guest.ts
export default defineNuxtRouteMiddleware(() => {
  const { isAuthenticated } = useAuth();

  if (isAuthenticated.value) {
    return navigateTo('/dashboard');
  }
});

最佳实践

  • 使用自动导入保持代码整洁
  • 利用 Nitro 构建 API 路由
  • 配置路由规则以实现最佳渲染
  • 使用 useFetch/useAsyncData 进行数据获取
  • 使用文件夹命名约定组织组件

目标流程

  • nuxt-全栈开发
  • vue-服务端渲染应用
  • jamstack-开发
  • api-开发