Vue 的 SSR(Nuxt.js)原理和适用场景?

Nuxt 3 基本结构

pages/
  index.vue       → /
  about.vue       → /about
  users/[id].vue  → /users/:id

server/
  api/            → API 路由

nuxt.config.ts    → 配置

自动路由

<!-- pages/index.vue -->
<template>
  <div>Home Page</div>
</template>

<!-- pages/users/[id].vue -->
<script setup>
const route = useRoute()
const { id } = route.params
</script>

数据获取

// useFetch — 自动序列化、去重、缓存
const { data: users } = await useFetch('/api/users')

// useAsyncData — 自定义数据获取
const { data } = await useAsyncData('users', () => {
  return $fetch('/api/users')
})

// 服务端获取数据,客户端水合

渲染模式

// nuxt.config.ts
export default defineNuxtConfig({
  // 默认 SSR
  ssr: true,
  
  // 或混合渲染
  routeRules: {
    '/': { prerender: true },          // 静态生成
    '/blog/**': { ssr: true },         // 服务端渲染
    '/admin/**': { ssr: false },       // SPA 模式
    '/api/**': { cors: true }          // API 路由
  }
})

Vue SSR 原理

// server-entry.js
import { createSSRApp } from 'vue'
import { renderToString } from 'vue/server-renderer'

export async function render(url) {
  const app = createSSRApp(App)
  const router = createRouter({ history: createMemoryHistory() })
  app.use(router)
  
  await router.push(url)
  await router.isReady()
  
  const html = await renderToString(app)
  return html
}

Hydration

// client-entry.js
import { createSSRApp } from 'vue'

const app = createSSRApp(App)
app.use(router)
app.mount('#app')
// Vue 自动检测已有 DOM,进行 hydration(复用 DOM 而非重新渲染)

Nuxt vs Next 对比

特性 Nuxt 3 Next 13+
框架 Vue 3 React 18
路由 文件系统 文件系统
数据获取 useFetch/useAsyncData server components
API 路由 server/api app/api
渲染模式 混合 混合
开发体验 零配置 零配置

适用场景

同分类其他题目