💚 Nuxt 3 全栈渲染链路

深度解析源码核心原理

基于源码深度解析
2026-03-18 | 技术深度解读

📑 目录

第一部分:基础架构

  • Nuxt 3 简介
  • 全栈渲染架构
  • 核心编译流程
  • 模块系统设计

第二部分:Nuxt 实例

  • createNuxt / initNuxt
  • 模块解析流程

第三部分:运行时

  • NuxtApp 创建
  • 插件系统
  • Hook 机制
  • SSR Context

第四部分:数据与路由

  • useAsyncData
  • 路由系统
  • 页面生成

💚 Nuxt 3 简介

Nuxt 3 是基于 Vue 3 的全栈框架,提供服务端渲染、静态生成、自动导入等特性。

核心特性

  • Vue 3 + Composition API
  • 自动代码分割
  • 文件系统路由
  • 服务端渲染 (SSR)
  • 静态站点生成 (SSG)
  • Nitro 服务端引擎

技术栈

  • Vite 构建工具
  • Vue Router 4
  • Pinia 状态管理
  • unhead 头部管理
  • h3 服务端框架
  • Treeshaking 优化

🏗️ 全栈渲染架构

┌─────────────────────────────────────────┐
│          Nuxt 3 全栈架构                 │
├─────────────────────────────────────────┤
│  ┌──────────┐  ┌──────────┐  ┌─────────┐│
│  │  Client  │  │  Server  │  │  Build  ││
│  └──────────┘  └──────────┘  └─────────┘│
│       ↓             ↓             ↓      │
│  ┌─────────────────────────────────────┐│
│  │      Nuxt App (运行时核心)           ││
│  │  • createNuxtApp()                  ││
│  │  • Plugin System                    ││
│  │  • Hook System                      ││
│  └─────────────────────────────────────┘│
│       ↓                                  │
│  ┌──────────┐  ┌──────────┐  ┌─────────┐│
│  │ useFetch │  │ useRouter│  │ useState││
│  └──────────┘  └──────────┘  └─────────┘│
│       ↓                                  │
│  ┌─────────────────────────────────────┐│
│  │         Nitro Server Engine         ││
│  └─────────────────────────────────────┘│
└─────────────────────────────────────────┘

⚙️ 核心编译流程

1. Nuxt 初始化 - 加载配置、解析模块

2. Vite 构建 - 客户端和服务端代码打包

3. Nitro 打包 - 服务端引擎构建

4. 路由生成 - 基于文件系统生成路由

5. 预渲染 - 静态页面生成(可选)

// nuxt.ts - Nuxt 初始化流程
export async function loadNuxt(opts: LoadNuxtOptions) {
    const nuxt = await createNuxt(opts)
    await initNuxt(nuxt)
    return nuxt
}

📦 模块系统设计

核心模块

  • nuxt:pages - 页面路由
  • nuxt:components - 组件自动导入
  • nuxt:imports - API 自动导入
  • nuxt:telemetry - 遥测数据

模块生命周期

  • modules:before - 模块加载前
  • modules:done - 模块加载完成
  • ready - Nuxt 就绪
  • close - Nuxt 关闭

模块定义: 使用 defineNuxtModule 创建可复用模块,支持钩子、配置和依赖管理。

🔷 Nuxt 实例创建

// nuxt.ts - 核心数据结构
export interface Nuxt {
  // 核心配置
  options: NuxtConfig
  hooks: Hookable<NuxtHooks>
  
  // 构建信息
  builder: NuxtBuilder | null
  vfs: Record<string, string>
  
  // 模块管理
  modules: NuxtModule[]
  plugins: NuxtPlugin[]
  
  // 资源
  templates: NuxtTemplate[]
  imports: Import[]
  components: Component[]
}

// Nuxt 实例是整个应用的核心
// 管理配置、模块、插件、模板等

🔧 createNuxt 源码解析

// nuxt.ts - 创建 Nuxt 实例
export async function createNuxt(options: NuxtOptions) {
  // 1. 创建基础实例
  const nuxt: Nuxt = {
    options,
    hooks: createHooks(),
    vfs: {},
    modules: [],
    plugins: [],
    templates: [],
    imports: [],
    components: [],
    // ... 其他属性
  }
  
  // 2. 设置构建器
  nuxt.builder = await loadBuilder(nuxt)
  
  // 3. 返回实例
  return nuxt
}

// 创建钩子系统
function createHooks() {
  return createHooks<NuxtHooks>()
}

🚀 initNuxt 初始化流程

// nuxt.ts - 初始化 Nuxt
export async function initNuxt(nuxt: Nuxt) {
  // 1. 执行 modules:before 钩子
  await nuxt.callHook('modules:before')
  
  // 2. 解析和安装模块
  await resolveModules(nuxt)
  
  // 3. 执行 modules:done 钩子
  await nuxt.callHook('modules:done')
  
  // 4. 生成模板
  await generateTemplates(nuxt)
  
  // 5. 准备构建
  await nuxt.callHook('ready')
}

// 模块解析是初始化的核心
async function resolveModules(nuxt: Nuxt) {
  for (const module of nuxt.options.modules) {
    await installModule(nuxt, module)
  }
}

🔄 模块解析流程

// module.ts - 安装模块
export async function installModule(
  nuxt: Nuxt, 
  module: NuxtModule | string
) {
  // 1. 解析模块路径
  const resolvedModule = typeof module === 'string'
    ? await import(module)
    : module
  
  // 2. 调用模块 setup 函数
  const result = await resolvedModule.setup(nuxt)
  
  // 3. 注册插件
  if (result?.plugins) {
    nuxt.plugins.push(...result.plugins)
  }
  
  // 4. 添加导入
  if (result?.imports) {
    nuxt.imports.push(...result.imports)
  }
  
  // 5. 执行钩子
  await nuxt.callHook('module:installed', resolvedModule)
}

🏃 应用运行时架构

Nuxt 运行时负责客户端和服务端的应用初始化、插件执行、数据管理等。

客户端运行时

  • Hydration(水合)
  • 插件初始化
  • 路由导航
  • 数据获取

服务端运行时

  • SSR 渲染
  • 数据预取
  • 路由匹配
  • Response 生成

📱 NuxtApp 接口

// app/nuxt.ts - NuxtApp 接口定义
export interface NuxtApp {
  // Vue 应用
  vueApp: App<Element>
  versions: Record<string, string>
  
  // Hook 系统
  hooks: Hookable<RuntimeNuxtHooks>
  hook: NuxtApp['hooks']['hook']
  callHook: NuxtApp['hooks']['callHook']
  
  // 上下文执行
  runWithContext: <T>(fn: T) => ReturnType<T>
  
  // 状态
  payload: NuxtPayload
  static: { data: Record<string, any> }
  
  // SSR
  ssrContext?: NuxtSSRContext
  isHydrating?: boolean
  
  // 注入
  provide: (name: string, value: any) => void
}

🛠️ createNuxtApp 源码

// app/nuxt.ts - 创建 NuxtApp
export function createNuxtApp(options: CreateOptions) {
  let hydratingCount = 0
  
  const nuxtApp: NuxtApp = {
    _id: options.id || 'nuxt-app',
    _scope: effectScope(),
    versions: { nuxt: __NUXT_VERSION__, vue: vueApp.version },
    
    // Payload 管理
    payload: shallowReactive({
      data: shallowReactive({}),
      state: reactive({}),
      once: new Set<string>(),
      _errors: shallowReactive({}),
    }),
    
    // Hydration 控制
    isHydrating: import.meta.client,
    deferHydration() { /* ... */ },
    
    // ... 其他属性
  }
  
  return nuxtApp
}

🔌 插件系统

Nuxt 插件在应用初始化时执行,可以注入全局属性、注册钩子、初始化第三方库。

// 插件定义
export interface Plugin {
  (nuxt: NuxtApp): Promise<void> | void
  meta?: ResolvedPluginMeta
}

// 定义插件
export function defineNuxtPlugin(plugin: Plugin) {
  return Object.assign(plugin, { 
    [NuxtPluginIndicator]: true 
  })
}

// 使用示例
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.provide('myPlugin', { /* ... */ })
})

⚡ applyPlugins 插件执行

// app/nuxt.ts - 执行插件
export async function applyPlugins(
  nuxtApp: NuxtApp, 
  plugins: Plugin[]
) {
  const resolvedPlugins = new Set<string>()
  const unresolvedPlugins = []
  
  // 插件依赖解析
  async function executePlugin(plugin: Plugin) {
    // 检查依赖
    const unresolved = plugin.dependsOn?.filter(
      name => !resolvedPlugins.has(name)
    )
    
    if (unresolved?.length > 0) {
      unresolvedPlugins.push([new Set(unresolved), plugin])
    } else {
      // 执行插件
      await applyPlugin(nuxtApp, plugin)
      resolvedPlugins.add(plugin._name)
    }
  }
  
  // 并行/串行执行
  for (const plugin of plugins) {
    await executePlugin(plugin)
  }
}

🪝 Hook 机制

应用 Hooks

  • app:created - 应用创建
  • app:beforeMount - 挂载前
  • app:mounted - 挂载完成
  • app:rendered - 渲染完成
  • app:error - 错误捕获

页面 Hooks

  • page:start - 页面开始
  • page:finish - 页面完成
  • page:loading:start
  • page:loading:end
  • page:transition:finish
// 注册 Hook
nuxtApp.hook('app:mounted', () => {
  console.log('App mounted!')
})

🖥️ SSR Context

// app/nuxt.ts - 服务端上下文
export interface NuxtSSRContext {
  url: string                    // 请求 URL
  event: H3Event                 // H3 事件对象
  runtimeConfig: RuntimeConfig   // 运行时配置
  noSSR: boolean                 // 是否禁用 SSR
  
  // Nuxt 实例
  nuxt: NuxtApp
  payload: Partial<NuxtPayload> // Payload 数据
  head: VueHeadClient            // Head 管理
  
  // 渲染控制
  error?: boolean
  teleports?: Record<string, string>
  
  // 内部属性
  ['~renderResponse']?: Partial<RenderResponse>
  ['~payloadReducers']: Record<string, (data: any) => any>
  ['~sharedPrerenderCache']?: { /* ... */ }
}

📦 Payload 传输

Payload是服务端渲染数据传输到客户端的核心机制。

// Payload 结构
export interface NuxtPayload {
  path?: string                  // 当前路径
  serverRendered?: boolean       // 是否 SSR
  prerenderedAt?: number         // 预渲染时间戳
  
  data: Record<string, any>      // 数据缓存
  state: Record<string, any>     // 应用状态
  once: Set<string>              // 单次标记
  
  config?: RuntimeConfig         // 配置
  error?: NuxtError              // 错误信息
  _errors: Record<string, NuxtError>
}

// 服务端设置
nuxtApp.payload.serverRendered = true
nuxtApp.payload.path = nuxtApp.ssrContext.url

// 客户端读取
const __NUXT__ = window.__NUXT__

📊 数据获取概览

Nuxt 3提供多个 composables 进行数据获取:useFetch、useAsyncData、useLazyFetch 等。

Composable 特点 使用场景
useFetch 封装 $fetch + useAsyncData HTTP 请求
useAsyncData 通用异步数据管理 任意异步操作
useLazyFetch 非阻塞加载 延迟数据
$fetch 原生 fetch 封装 简单请求

🎯 useAsyncData 源码

// composables/asyncData.ts - 核心 API
export function useAsyncData<ResT>(
  key: MaybeRefOrGetter<string>,
  handler: AsyncDataHandler<ResT>,
  opts?: AsyncDataOptions<ResT>
): AsyncData<ResT> {
  const nuxtApp = useNuxtApp()
  
  // 1. 获取或创建 AsyncData 实例
  if (!nuxtApp._asyncData[key]) {
    nuxtApp._asyncData[key] = buildAsyncData(
      nuxtApp, key, handler, opts
    )
  }
  
  // 2. 服务端:立即执行
  if (import.meta.server && opts.server !== false) {
    nuxtApp._asyncData[key].execute()
  }
  
  // 3. 客户端:从 payload 恢复或执行
  if (import.meta.client) {
    if (nuxtApp.isHydrating && nuxtApp.payload.data[key]) {
      // Hydration: 使用服务端数据
    } else {
      nuxtApp._asyncData[key].execute()
    }
  }
  
  return nuxtApp._asyncData[key]
}

⚙️ AsyncDataOptions 配置

// composables/asyncData.ts - 配置选项
export interface AsyncDataOptions<ResT> {
  // 服务端行为
  server?: boolean        // 是否在服务端执行(默认 true)
  lazy?: boolean          // 是否延迟加载(默认 false)
  
  // 数据处理
  default?: () => DefaultT           // 默认值
  transform?: (data: ResT) => DataT  // 数据转换
  pick?: KeysOf<DataT>               // 提取字段
  
  // 缓存
  getCachedData?: (key, nuxtApp) => DataT
  
  // 响应式
  watch?: MultiWatchSources         // 监听源
  immediate?: boolean               // 立即执行
  
  // 性能
  deep?: boolean                   // 深度响应(默认 true)
  dedupe?: 'cancel' | 'defer'     // 去重策略
  timeout?: number                 // 超时时间
}

🏗️ buildAsyncData 构建

// composables/asyncData.ts - 构建 AsyncData
function buildAsyncData(
  nuxtApp: NuxtApp,
  key: string,
  handler: AsyncDataHandler,
  options: AsyncDataOptions
) {
  const asyncData = {
    // 响应式状态
    data: ref(options.default()),
    pending: ref(true),
    error: ref(undefined),
    status: shallowRef('idle'),
    
    // 执行方法
    async execute(opts?: AsyncDataExecuteOptions) {
      asyncData.status.value = 'pending'
      
      try {
        const result = await handler(nuxtApp, { signal })
        
        // 数据转换
        let data = options.transform 
          ? await options.transform(result) 
          : result
        
        asyncData.data.value = data
        asyncData.status.value = 'success'
        
        // 保存到 payload
        nuxtApp.payload.data[key] = data
      } catch (err) {
        asyncData.error.value = err
        asyncData.status.value = 'error'
      }
    }
  }
  
  return asyncData
}

💾 缓存策略

Payload 缓存

  • 服务端数据注入到 HTML
  • 客户端直接使用,避免重复请求
  • 自动去重

静态缓存

  • nuxtApp.static.data
  • 跨页面共享
  • 需手动管理

自定义缓存

const { data } = await useFetch('/api/data', {
  getCachedData(key, nuxtApp) {
    // 自定义缓存逻辑
    return nuxtApp.static.data[key]
  }
})

🌐 useFetch 源码

// composables/fetch.ts - useFetch 实现
export const useFetch = createUseFetch({
  name: 'createUseFetch',
  factory() {
    return function useFetch(request, opts = {}) {
      // 1. 生成请求 key
      const key = computed(() => 
        '$f' + hash([request, ...generateOptionSegments(opts)])
      )
      
      // 2. 合并默认选项
      const _fetchOptions = reactive({
        ...fetchDefaults,
        ...opts
      })
      
      // 3. 调用 useAsyncData
      return useAsyncData(key, () => {
        const _$fetch = opts.$fetch || $fetch
        return _$fetch(request, { 
          signal, 
          ..._fetchOptions 
        })
      }, {
        server: opts.server,
        lazy: opts.lazy,
        watch: [request, _fetchOptions]
      })
    }
  }
})

🔄 请求去重机制

// composables/asyncData.ts - 去重逻辑
function execute(opts) {
  // 1. 检查是否有进行中的请求
  if (nuxtApp._asyncDataPromises[key]) {
    if ((opts.dedupe ?? options.dedupe) === 'defer') {
      // defer: 等待现有请求
      return nuxtApp._asyncDataPromises[key]
    }
    // cancel: 取消现有请求
  }
  
  // 2. 创建新请求
  const promise = handler(nuxtApp, { signal })
    .then(result => {
      // 保存结果
      asyncData.data.value = result
      delete nuxtApp._asyncDataPromises[key]
    })
  
  // 3. 存储请求 Promise
  nuxtApp._asyncDataPromises[key] = promise
  
  return promise
}

🛣️ 路由系统

Nuxt 路由基于文件系统自动生成,支持动态路由、嵌套路由、中间件等。

路由文件

  • pages/index.vue → /
  • pages/about.vue → /about
  • pages/users/[id].vue → /users/:id
  • pages/posts/[...slug].vue → /posts/*

路由特性

  • 自动导入
  • 路由守卫
  • 页面过渡
  • 预加载
  • 路由元信息

🔀 useRouter / useRoute

// composables/router.ts - 路由访问
export const useRouter = () => {
  return useNuxtApp()?.$router as Router
}

export const useRoute = () => {
  // 优先从注入获取(支持嵌套路由)
  if (hasInjectionContext()) {
    return inject(PageRouteSymbol, useNuxtApp()._route)
  }
  return useNuxtApp()._route
}

// 使用示例
const router = useRouter()
const route = useRoute()

// 导航
router.push('/about')

// 获取参数
const id = route.params.id

🚀 navigateTo 导航函数

// composables/router.ts - 导航函数
export const navigateTo = (
  to: RouteLocationRaw | undefined | null,
  options?: NavigateToOptions
) => {
  // 1. 处理外部链接
  if (isExternal) {
    if (options?.replace) {
      location.replace(toPath)
    } else {
      location.href = toPath
    }
    return
  }
  
  // 2. 服务端:设置 redirect
  if (import.meta.server) {
    nuxtApp.ssrContext!['~renderResponse'] = {
      status: options?.redirectCode || 302,
      headers: { location: encodedHeader }
    }
    return
  }
  
  // 3. 客户端:vue-router 导航
  return options?.replace 
    ? router.replace(encodedTo) 
    : router.push(encodedTo)
}

🛡️ 路由中间件

// composables/router.ts - 中间件系统
export interface RouteMiddleware {
  (to: RouteLocationNormalized, from: RouteLocationNormalized): 
    ReturnType<NavigationGuard>
}

// 定义中间件
export function defineNuxtRouteMiddleware(middleware: RouteMiddleware) {
  return middleware
}

// 注册中间件
export const addRouteMiddleware = (
  name: string | RouteMiddleware,
  middleware?: RouteMiddleware,
  options?: { global?: boolean }
) => {
  if (global || typeof name !== 'string') {
    nuxtApp._middleware.global.push(mw)
  } else {
    nuxtApp._middleware.named[name] = mw
  }
}

// 使用示例
export default defineNuxtRouteMiddleware((to, from) => {
  if (!isAuthenticated()) {
    return navigateTo('/login')
  }
})

📄 页面模块 (nuxt:pages)

// pages/module.ts - 页面模块
export default defineNuxtModule({
  meta: { name: 'nuxt:pages' },
  
  async setup(options, nuxt) {
    // 1. 扫描 pages 目录
    const pagesDirs = getLayerDirectories(nuxt)
      .map(dirs => dirs.appPages)
    
    // 2. 解析路由
    const resolvePagesRoutes = async (pattern) => {
      const pages = await _resolvePagesRoutes(pattern, nuxt)
      await handleRouteRules(pages)
      return pages
    }
    
    // 3. 生成路由文件
    addTemplate({
      filename: 'routes.mjs',
      getContents({ app }) {
        const { routes, imports } = normalizeRoutes(app.pages)
        return [...imports, `export default ${routes}`].join('\n')
      }
    })
  }
})

🗺️ 路由生成流程

// 路由生成流程
┌────────────────────────────────────┐
│  pages/                            │
│  ├── index.vue                     │
│  ├── about.vue                     │
│  └── users/[id].vue                │
└─────────────┬──────────────────────┘
              ↓
┌────────────────────────────────────┐
│  resolvePagesRoutes()              │
│  • 扫描文件                        │
│  • 解析路径                        │
│  • 提取元信息                      │
└─────────────┬──────────────────────┘
              ↓
┌────────────────────────────────────┐
│  normalizeRoutes()                 │
│  • 生成 vue-router 配置            │
│  • 添加动态导入                    │
│  • 设置路由守卫                    │
└─────────────┬──────────────────────┘
              ↓
┌────────────────────────────────────┐
│  routes.mjs                        │
│  export default [                  │
│    { path: '/', component: ... },  │
│    { path: '/about', ... },        │
│    { path: '/users/:id', ... }     │
│  ]                                 │
└────────────────────────────────────┘

📦 服务端打包

Nuxt 3使用 Nitro 作为服务端引擎,支持多种部署目标(Node、Serverless、Edge)。

打包流程

  • 1. 扫描 server/ 目录
  • 2. 构建 API 路由
  • 3. 打包中间件
  • 4. 生成 Nitro 配置
  • 5. 编译到目标平台

部署目标

  • Node.js Server
  • Vercel / Netlify
  • AWS Lambda
  • Cloudflare Workers
  • 静态站点

🔧 bundleServer 源码

// core/server.ts - 服务端打包
export async function bundleServer(nuxt: Nuxt) {
  try {
    // 1. 加载服务端构建器
    const { bundle } = !nuxt.options.server.builder 
      ? await loadServerBuilder(nuxt)
      : nuxt.options.server.builder
    
    // 2. 执行打包
    await bundle(nuxt)
    
  } catch (error: any) {
    // 3. 错误处理
    await nuxt.callHook('build:error', error)
    throw error
  }
}

// 加载默认构建器
async function loadServerBuilder(nuxt: Nuxt) {
  return await importModule('@nuxt/nitro-server', {
    url: [directoryToURL(nuxt.options.rootDir)]
  })
}

⚡ Nitro 集成

// Nitro 是 Nuxt 的服务端引擎
// 特性:
// • 跨平台部署
// • 自动代码分割
// • 文件系统 API
// • 热重载
// • 缓存策略

// server/api/hello.ts
export default defineEventHandler((event) => {
  return { message: 'Hello Nuxt!' }
})

// server/middleware/auth.ts
export default defineEventHandler((event) => {
  const auth = getHeader(event, 'authorization')
  if (!auth) {
    throw createError({
      statusCode: 401,
      message: 'Unauthorized'
    })
  }
})

🎨 渲染流程

// SSR 渲染流程
┌─────────────────────────────────┐
│  客户端请求                      │
│  GET /users/123                 │
└────────────┬────────────────────┘
             ↓
┌─────────────────────────────────┐
│  Nitro Server                   │
│  • 路由匹配                      │
│  • 创建 SSRContext              │
└────────────┬────────────────────┘
             ↓
┌─────────────────────────────────┐
│  createNuxtApp()                │
│  • 初始化应用                    │
│  • 执行插件                      │
│  • 运行中间件                    │
└────────────┬────────────────────┘
             ↓
┌─────────────────────────────────┐
│  useAsyncData 执行              │
│  • 数据预取                      │
│  • 保存到 payload               │
└────────────┬────────────────────┘
             ↓
┌─────────────────────────────────┐
│  Vue SSR Renderer               │
│  • renderToString()             │
│  • 生成 HTML                    │
│  • 注入 payload                 │
└────────────┬────────────────────┘
             ↓
┌─────────────────────────────────┐
│  返回 HTML + __NUXT__           │
└─────────────────────────────────┘

💧 Hydration(水合)

Hydration是客户端接管服务端渲染的 HTML,使其变为可交互的 Vue 应用的过程。

// app/nuxt.ts - Hydration 控制
const nuxtApp: NuxtApp = {
  isHydrating: import.meta.client,
  
  deferHydration() {
    if (!nuxtApp.isHydrating) return () => {}
    
    hydratingCount++
    let called = false
    
    return () => {
      if (called) return
      called = true
      hydratingCount--
      
      if (hydratingCount === 0) {
        nuxtApp.isHydrating = false
        return nuxtApp.callHook('app:suspense:resolve')
      }
    }
  }
}

// 使用:延迟 Hydration
const defer = nuxtApp.deferHydration()
// ... 异步操作完成后
defer()

🗄️ 状态管理

useState

// 跨组件共享状态
const counter = useState('counter', () => 0)

// 等价于
const counter = useState('counter')
if (!counter.value) {
  counter.value = 0
}

Pinia 集成

// stores/user.ts
export const useUserStore = defineStore('user', {
  state: () => ({
    name: '',
    email: ''
  }),
  actions: {
    async fetchUser() {
      const data = await $fetch('/api/user')
      this.name = data.name
    }
  }
})

📥 自动导入

// Nuxt 自动导入机制
// 1. 内置 composables
//    useFetch, useState, useRouter...

// 2. 组件自动导入
//    components/ 目录下的组件

// 3. 工具函数自动导入
//    utils/ 目录下的函数

// 4. 自定义导入
// nuxt.config.ts
export default defineNuxtConfig({
  imports: {
    dirs: ['composables', 'utils']
  }
})

// 生成的 imports.d.ts
declare global {
  const useState: typeof import('#app')['useState']
  const useFetch: typeof import('#app')['useFetch']
  // ...
}

🏝️ 组件 Islands 架构

Islands允许组件独立渲染,减少客户端 JavaScript 负载。

// 服务端组件
// components/Comments.server.vue
<template>
  <div class="comments">
    <!-- 仅在服务端渲染 -->
    {{ comments }}
  </div>
</template>

// 客户端组件
// components/Interactive.client.vue
<template>
  <button @click="handleClick">
    Click me
  </button>
</template>

// 使用
<Comments />  <!-- 服务端 -->
<Interactive />  <!-- 客户端 -->

⚙️ 预渲染 (Prerendering)

// pages/module.ts - 预渲染配置
nuxt.hook('nitro:build:before', (nitro) => {
  // 注入 SSR 路由
  nitro.options.ssrRoutes = [
    ...nitro.options.ssrRoutes || [],
    ...toRou3Patterns(nuxt.apps.default?.pages || [])
  ]
  
  // 预渲染配置
  nitro.options.prerender.routes ||= []
  
  // 添加静态页面
  if (nitro.options.static) {
    for (const route of prerenderRoutes) {
      const rules = nitro.routing.routeRules.matchAll('', route)
      if (rules.prerender) {
        nitro.options.prerender.routes.push(route)
      }
    }
  }
})

// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ['/', '/about', '/contact']
    }
  }
})

🚀 性能优化策略

构建优化

  • Vite 快速构建
  • Tree-shaking
  • 代码分割
  • 模块预加载

运行时优化

  • Payload 传输
  • Hydration 优化
  • 组件懒加载
  • 请求去重

缓存策略

  • 静态资源缓存
  • API 响应缓存
  • Payload 缓存
  • CDN 缓存

监控

  • Core Web Vitals
  • Hydration 性能
  • 构建时间
  • 包体积分析

🎨 设计模式

工厂模式

  • createNuxtApp
  • createUseFetch
  • defineNuxtModule

观察者模式

  • Hook 系统
  • 事件监听
  • 状态订阅

组合模式

  • Composables
  • 插件系统
  • 中间件链

代理模式

  • $fetch 封装
  • 响应式代理
  • 配置代理

⚔️ 与其他框架对比

特性 Nuxt 3 Next.js SvelteKit
基础框架 Vue 3 React Svelte
构建工具 Vite Turbopack/Webpack Vite
服务端引擎 Nitro Node.js Node.js
自动导入
文件路由
SSR

✅ 最佳实践

数据获取

  • 使用 useFetch 代替 $fetch
  • 设置合适的 key
  • 利用缓存机制
  • 懒加载非关键数据

状态管理

  • useState 简单状态
  • Pinia 复杂状态
  • 避免全局污染

性能优化

  • 组件懒加载
  • 图片优化
  • 代码分割
  • 预加载关键资源

SEO

  • useHead 设置 meta
  • SSR/SSG
  • 站点地图
  • 结构化数据

❓ 常见问题

Q: Hydration mismatch 错误?

A: 确保服务端和客户端渲染一致,避免在渲染时使用浏览器 API。

Q: useFetch 数据重复请求?

A: 检查 key 是否唯一,使用 dedupe 选项,确保 payload 正确传递。

Q: 插件执行顺序?

A: 使用 enforce: 'pre'/'post',dependsOn 指定依赖,parallel 并行执行。

🐛 调试技巧

// 1. 开启调试模式
// nuxt.config.ts
export default defineNuxtConfig({
  debug: true
})

// 2. 查看 Hook 调用
nuxtApp.hook('app:created', () => {
  console.log('App created', nuxtApp)
})

// 3. Payload 调试
console.log('Payload:', nuxtApp.payload)
console.log('Static data:', nuxtApp.static.data)

// 4. 路由调试
console.log('Routes:', useRouter().getRoutes())

// 5. 组件状态
const { data, pending, error } = await useFetch('/api/data')
watchEffect(() => {
  console.log('Data:', data.value)
  console.log('Pending:', pending.value)
  console.log('Error:', error.value)
})

🔮 未来展望

即将推出

  • View Transitions API
  • 增强的 Islands
  • 更快的 Hydration
  • Edge Runtime 支持

社区趋势

  • 服务端组件
  • 零配置部署
  • AI 集成
  • 更好的 DX

Nuxt 3正在快速演进,持续关注 RFC 和官方博客获取最新特性。

📊 架构总览

┌──────────────────────────────────────┐
│         Nuxt 3 全栈渲染链路           │
├──────────────────────────────────────┤
│  构建时                               │
│  ├─ createNuxt() 创建实例            │
│  ├─ initNuxt() 初始化                │
│  ├─ resolveModules() 解析模块        │
│  └─ bundleServer() 服务端打包        │
├──────────────────────────────────────┤
│  运行时                               │
│  ├─ createNuxtApp() 创建应用         │
│  ├─ applyPlugins() 执行插件          │
│  ├─ useAsyncData() 数据获取          │
│  └─ useRouter() 路由管理             │
├──────────────────────────────────────┤
│  服务端                               │
│  ├─ Nitro Server Engine              │
│  ├─ SSR Context                      │
│  ├─ Payload 传输                     │
│  └─ HTML 渲染                        │
├──────────────────────────────────────┤
│  客户端                               │
│  ├─ Hydration 水合                   │
│  ├─ 状态恢复                         │
│  └─ 交互激活                         │
└──────────────────────────────────────┘

🗂️ 源码导航

文件路径 功能
packages/nuxt/src/core/nuxt.ts Nuxt 实例创建
packages/nuxt/src/core/server.ts 服务端打包
packages/nuxt/src/app/nuxt.ts 应用运行时
packages/nuxt/src/app/composables/asyncData.ts 数据获取
packages/nuxt/src/app/composables/fetch.ts HTTP 请求
packages/nuxt/src/app/composables/router.ts 路由系统
packages/nuxt/src/pages/module.ts 页面模块

🎯 总结

Nuxt 3是一个精心设计的全栈框架,通过模块化架构、插件系统和 Nitro 引擎实现了灵活高效的开发体验。

核心优势

  • Vue 3 + Composition API
  • 自动导入和代码分割
  • 灵活的渲染模式
  • 强大的 Nitro 引擎
  • 优秀的开发体验

关键概念

  • Nuxt 实例生命周期
  • 插件和 Hook 系统
  • 数据获取和缓存
  • SSR 和 Hydration
  • Payload 传输机制

感谢阅读! 🎉