SuperAPI AI 工具集

nuxt

前端与建站

查看项目

更新于 10-16 14:57

技能介绍

Nuxt 是一个直观的 Vue.js 全栈框架,提供自动路由、服务端渲染(SSR)、静态站点生成(SSG)以及经过优化的 Nitro 服务器引擎性能。

适用场景

  • 全栈 Vue 3 Web 应用:Nuxt 3/4,支持通用 SSR、静态生成(SSG)和自动导入。
  • 企业级 SEO 与快速加载页面:需要动态 meta 标签和即时渲染的营销站点与电商商店。
  • 边缘就绪的服务器引擎(Nitro):将 Serverless 函数无缝部署到 Cloudflare、Vercel、Netlify 和 Node。
  • 模块化前端架构:使用第一方模块(@nuxtjs/tailwindcss、@pinia/nuxt、@vueuse/nuxt)。

快速开始

Nuxt 会自动导入组件和组合式函数。

<script setup> // useFetch 已自动导入 const { data: quote } = await useFetch("/api/quote"); </script>

<template> <blockquote>{{ quote.text }}</blockquote> </template>

核心概念

使用 useFetch 与 useAsyncData 的通用数据获取

支持 SSR 的数据获取,并具备自动去重能力:

<!-- pages/products/[id].vue --> <script setup lang="ts"> interface Product { id: number; title: string; price: number; }

const route = useRoute(); const productId = route.params.id;

const { data: product, pending, error, } = await useFetch<Product>(/api/products/${productId}, { key: product-${productId}, lazy: false, });

useSeoMeta({ title: () => product.value?.title ? ${product.value.title} - Store : "Loading...", description: () => Buy ${product.value?.title} online now., }); </script>

<template> <div class="product-page"> <div v-if="pending">Loading product details...</div> <div v-else-if="error">Error loading product: {{ error.message }}</div> <div v-else-if="product"> <h1>{{ product.title }}</h1> <p class="price">${{ product.price }}</p> </div> </div> </template>

Nitro 服务器引擎 API 路由

直接在 server/api 内创建后端 API 端点:

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

if (!id || isNaN(Number(id))) { throw createError({ statusCode: 400, statusMessage: "Invalid product ID", }); }

return { id: Number(id), title: Premium Mechanical Keyboard #${id}, price: 149.99, }; });

Nuxt 中间件与路由守卫

客户端与服务端路由身份验证:

// middleware/auth.ts export default defineNuxtRouteMiddleware((to, from) => { const user = useCookie("auth_token");

if (!user.value && to.path.startsWith("/dashboard")) { return navigateTo("/login"); } });

常见模式

服务端 API 路由配合 useFetch 数据水合

问题:客户端获取数据会导致内容闪烁,并影响搜索引擎索引。

解决方案: 使用 Nuxt 服务端路由搭配通用 useFetch:

// server/api/products.ts export default defineEventHandler(async (event) => { return await db.products.findMany({ take: 20 }); });

// pages/products.vue <script setup> const { data: products, pending, error } = await useFetch('/api/products'); </script>

<template> <div v-if="pending">Loading products...</div> <ul v-else> <li v-for="p in products" :key="p.id">{{ p.name }} - ${{ p.price }}</li> </ul> </template>

最佳实践

推荐做法:

  • 在 <script setup> 内使用 useFetch 进行顶层组件数据获取,以消除 SSR 双重获取。
  • 利用 Nuxt 服务端 API 路由(server/api/)进行后端代理和密钥保护。
  • 使用 useSeoMeta() 实现响应式、类型安全的 SEO 管理。
  • 启用 Nitro 路由规则(routeRules)进行细粒度缓存和按页面的 ISR。

不推荐做法:

  • 在 setup 脚本中直接使用标准 fetch();它会在服务端和客户端都执行,且没有水合传输。
  • 在 onMounted 之外访问 window 或 document,或未检查 import.meta.client。
  • 跨用户请求修改服务端状态。

故障排查

错误 | 原因 | 解决方案

window is not defined / document is not defined | 在服务端预渲染步骤中访问浏览器 DOM。 | 将浏览器代码包裹在 onMounted(() => { ... }) 或 <ClientOnly> 中。

[nuxt] [request error] [unhandled] 500 | 服务端路由抛出未处理异常。 | 检查终端控制台输出的服务端堆栈跟踪,并用 try/catch 包裹。

Component not found on auto-import | 嵌套文件夹结构要求组件名带路径前缀。 | 遵循命名约定:components/base/Button.vue -> <BaseButton />。

参考资料

Nuxt 文档