Nuxt: Nuxt 3 简介与 SSR 概念

Charlie 正在为他的电商平台 MegaShop 挑选技术栈——百万级商品页面需要极致 SEO,首屏加载必须够快。传统的 CSR 方案让搜索引擎抓不到商品数据,流量惨淡。Nuxt 3 的 SSR 能力正是他的解药。

1. 你将学到


2. 一个架构师的真实故事

(1) 痛点:CSR 让百万商品页"隐形"

Charlie 的 MegaShop 有 over 1 million 商品页面,但使用纯 CSR(客户端渲染)后,Google 爬虫只能拿到一个空 <div id="app"></div>——商品标题、价格、描述全部缺席。SEO 排名跌到第 5 页,Alice(消费者)根本搜不到商品,Bob(管理员)看着接近零的有机流量发愁。

(2) Nuxt 3 SSR 的解法

Nuxt 3 在服务端预先渲染 HTML,爬虫拿到的是完整的商品页面——标题、价格、结构化数据一应俱全。Charlie 只需创建项目,SSR 就开箱即用:

BASH
# Create Nuxt 3 project with SSR enabled by default
npx nuxi@latest init megashop

(3) 收益:SEO 流量飙升

切换到 Nuxt 3 SSR 后,MegaShop 的 Google 索引页面从 2 thousand 飙升到 800 thousand,有机流量增长 340%,首屏加载从 4.2s 降到 1.1s。


3. Nuxt 3 与 Vue 3 的关系

Nuxt 3 是基于 Vue 3 的全栈框架,由 Vue 核心团队成员 Sébastien Chopin 主导开发。

(1) 定位对比

维度 Vue 3 Nuxt 3
定位 渐进式 UI 框架 Vue 3 全栈元框架
渲染 仅 CSR SSR / CSR / SSG / ISR / ESR
路由 手动配置 vue-router 文件路由自动生成
数据获取 手动封装 useFetch / useAsyncData
构建 需选配 Vite/Webpack 内置 Vite
服务端 Nitro 服务器引擎
Auto-import 组件/Composable/工具函数

(2) Nuxt 3 的核心价值

💡 提示: Nuxt 3 不是 Vue 3 的替代品,而是在 Vue 3 之上提供工程化全栈能力的企业级框架。


4. 五种渲染模式对比

(1) 渲染模式全景图

100%
flowchart TB
    A[User Request] --> B{Rendering Mode}
    B -->|SSR| C[Server renders HTML<br/>on every request]
    B -->|CSR| D[Browser renders HTML<br/>after JS download]
    B -->|SSG| E[HTML pre-built<br/>at build time]
    B -->|ISR| F[HTML cached +<br/>revalidate on interval]
    B -->|ESR| G[Edge CDN renders<br/>closest to user]
    C --> H[Full HTML response]
    D --> I[Empty shell + JS bundle]
    E --> H
    F --> H
    G --> H

(2) 五种模式核心对比

维度 SSR CSR SSG ISR ESR
渲染时机 每次请求 浏览器端 构建时 缓存+定时验证 CDN 边缘节点
SEO 友好 ✅ 优秀 ❌ 差 ✅ 优秀 ✅ 优秀 ✅ 优秀
首屏速度 ⚡ 快 🐢 慢 ⚡⚡ 最快 ⚡⚡ 快 ⚡⚡⚡ 最快
数据实时性 ✅ 实时 ✅ 实时 ❌ 静态 ⚠️ 定时更新 ⚠️ 定时更新
服务器压力 🔴 高 🟢 低 🟢 最低 🟡 中 🟡 中
适用场景 动态详情页 后台管理 博客/文档 商品列表 全球化页面

(3) SSR 工作流程详解

SSR(Server-Side Rendering)是 Nuxt 3 的默认渲染模式,核心流程:

  1. 用户请求 URL
  2. Nuxt 服务端执行 Vue 组件渲染
  3. 生成完整 HTML 字符串
  4. 发送 HTML 到浏览器
  5. 浏览器展示页面(首屏可见)
  6. 下载 JS 并"水合"(hydration),绑定事件

▶ 示例:SSR vs CSR 响应对比

HTML
<!-- SSR response: full HTML with content -->
<div id="app">
  <h1>MegaShop - Premium Headphones</h1>
  <p>Price: $299.99 USD</p>
  <p>1.2 thousand reviews</p>
</div>

<!-- CSR response: empty shell -->
<div id="app"></div>
<script src="/bundle.js"></script>

输出:

TEXT 📖 仅展示
// 执行成功

▶ 示例:Nuxt 3 SSR 页面

VUE
<!-- pages/index.vue -->
<template>
  <div>
    <h1>{{ product.name }}</h1>
    <p>Price: ${{ product.price }} USD</p>
  </div>
</template>

<script setup lang="ts">
// Data fetched on server, included in HTML response
const { data: product } = await useFetch('/api/products/featured')
</script>

输出:

TEXT 📖 仅展示
// 执行成功

▶ 示例:CSR 模式页面

VUE
<!-- pages/dashboard.vue - client-only page -->
<template>
  <div>
    <h1>Admin Dashboard</h1>
    <p>Welcome, Bob</p>
  </div>
</template>

<script setup lang="ts">
// Force client-side rendering
definePageMeta({
  ssr: false
})

const { data: stats } = await useFetch('/api/admin/stats')
</script>

输出:

TEXT 📖 仅展示
// 执行成功

5. Nuxt 3 核心架构

(1) 架构组成

100%
graph TB
    A[Nuxt 3] --> B[Vite - Build Tool]
    A --> C[Vue 3 - UI Framework]
    A --> D[Nitro - Server Engine]
    A --> E[Auto-imports System]
    D --> F[H3 - HTTP Framework]
    D --> G[Storage Layer]
    D --> H[Cache API]
    E --> I[Components]
    E --> J[Composables]
    E --> K[Utilities]

(2) 核心模块职责

模块 职责 MegaShop 应用
Vite 构建工具,HMR 极速热更新 开发时秒级刷新商品页
Vue 3 Composition API + 响应式 组件化商品卡片/购物车
Nitro 服务端引擎,多预设部署 API 路由 + ISR 缓存
Auto-imports 组件/函数自动注册 免 import 直接用 useFetch
H3 轻量 HTTP 框架 处理 API 请求与中间件

▶ 示例:Auto-imports 效果

VUE
<!-- No manual imports needed -->
<template>
  <div>
    <ProductCard :product="item" />
    <!-- ProductCard auto-imported from components/ -->
  </div>
</template>

<script setup lang="ts">
// useFetch, useState, useRouter - all auto-imported
const { data: item } = await useFetch('/api/products/1')
const router = useRouter()
const cart = useState('cart', () => [])
</script>

输出:

TEXT 📖 仅展示
// 执行成功

▶ 示例:Nitro API Route

TYPESCRIPT
// server/api/products/index.ts
export default defineEventHandler(async (event) => {
  const query = getQuery(event)
  const page = Number(query.page) || 1
  const limit = Number(query.limit) || 20

  // Fetch products with pagination
  const products = await fetchProducts(page, limit)

  return {
    items: products,
    total: 1000000, // 1 million products
    page,
    limit
  }
})

输出:

TEXT 📖 仅展示
// 执行成功

6. MegaShop 场景分析

(1) 为什么百万级商品页必须选 SSR

需求 CSR 表现 SSR 表现
Google 索引率 < 5% > 95%
首屏 LCP 3.5-5s 0.8-1.5s
商品名出现在 HTML ❌ 需等 JS ✅ 直接包含
结构化数据支持 ❌ 爬虫看不到 ✅ 完整输出
社交分享预览 ❌ 空白 ✅ 正确显示

▶ 示例:MegaShop 商品页 SSR 输出

HTML
<!-- Server-rendered HTML for /products/headphones-123 -->
<!DOCTYPE html>
<html>
<head>
  <title>Premium Headphones - MegaShop</title>
  <meta name="description" content="Premium wireless headphones, $299.99 USD">
  <script type="application/ld+json">
  {
    "@type": "Product",
    "name": "Premium Headphones",
    "price": "299.99",
    "priceCurrency": "USD",
    "aggregateRating": { "ratingValue": "4.8", "reviewCount": "1200" }
  }
  </script>
</head>
<body>
  <div id="app">
    <h1>Premium Headphones</h1>
    <p>$299.99 USD</p>
    <p>1.2 thousand reviews · 4.8 stars</p>
  </div>
</body>
</html>

输出:

TEXT 📖 仅展示
// 执行成功

7. Nuxt 3 生态全景

(1) 官方模块生态

模块 功能 MegaShop 用途
@nuxtjs/tailwindcss CSS 框架集成 响应式布局
@nuxt/image 图片优化 WebP 转换 + 懒加载
@nuxtjs/i18n 国际化 中文/英文/日文
@nuxtjs/sitemap Sitemap 生成 百万页 SEO
@pinia/nuxt 状态管理 购物车/用户状态
@nuxt/devtools 开发者工具 调试与性能分析

(2) 社区规模

▶ 示例:安装官方模块

BASH
# Install Tailwind CSS module
npm install @nuxtjs/tailwindcss

# Install Pinia state management
npm install @pinia/nuxt

# Install i18n module
npm install @nuxtjs/i18n

输出:

TEXT 📖 仅展示
# 命令执行成功
TYPESCRIPT
// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/tailwindcss',
    '@pinia/nuxt',
    '@nuxtjs/i18n'
  ]
})

8. 综合示例:MegaShop SSR 商品页

VUE
<!-- pages/products/[id].vue -->
<template>
  <div class="product-page">
    <h1>{{ product?.name }}</h1>
    <p class="price">${{ product?.price }} USD</p>
    <p>{{ product?.reviewCount }} reviews</p>
    <button @click="addToCart(product)">
      Add to Cart
    </button>
  </div>
</template>

<script setup lang="ts">
interface Product {
  id: number
  name: string
  price: number
  reviewCount: number
}

// SSR: data fetched on server, included in initial HTML
const route = useRoute()
const { data: product } = await useFetch<Product>(`/api/products/${route.params.id}`)

// SEO metadata
useHead({
  title: `${product.value?.name} - MegaShop`,
  meta: [
    { name: 'description', content: `Buy ${product.value?.name} for $${product.value?.price} USD` }
  ]
})

const cart = useState<Product[]>('cart', () => [])
function addToCart(item: Product | null) {
  if (item) cart.value.push(item)
}
</script>

❓ 常见问题

Q Nuxt 3 和 Next.js 有什么区别?
A Nuxt 3 基于 Vue 3 + Vite,Next.js 基于 React + Webpack/Turbopack。Nuxt 3 的 auto-imports 和文件约定更彻底,Nitro 引擎支持更多部署预设。
Q SSR 会不会让服务器压力很大?
A 对高流量页面可以用 ISR 缓存或 ESR 边缘渲染来降低服务器压力。Nuxt 3 的 routeRules 允许每条路由独立配置渲染策略。
Q Nuxt 3 能不能不用 SSR?
A 可以。在 nuxt.config.ts 设置 ssr: false 即可全局关闭 SSR,也可以用 definePageMeta 对单页关闭。后台管理页面通常用 CSR。
Q SSR 页面能使用浏览器 API 吗?
A SSR 阶段没有浏览器环境,直接用 window/document 会报错。需要放在 onMounted 里或用 import.meta.client 判断。
Q Nuxt 3 是否支持 TypeScript?
A 原生支持。Nuxt 3 自动生成 .nuxt/tsconfig.json,组件/Composable/API 都有完整的类型推导,无需手动配置。
Q MegaShop 百万商品页怎么保证构建速度?
A 不预构建所有页面。用 SSR 按请求渲染 + ISR 缓存热门页,构建时只预渲染关键页(首页/分类页),商品详情页走 SSR+ISR。

📖 小节


📝 作业

  1. 基础题(难度⭐):用 npx nuxi@latest init 创建一个 Nuxt 3 项目,观察默认配置中 SSR 是否开启
  2. 进阶题(难度⭐⭐):在项目首页用 useFetch 获取一个公开 API 数据,对比浏览器"查看源代码"中是否包含数据(验证 SSR)
  3. 挑战题(难度⭐⭐⭐):创建一个 CSR 模式的页面(definePageMeta({ ssr: false })),对比它与 SSR 页面在"查看源代码"时的差异

---|

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏