服务器的渲染方式
1. 客户端渲染 (CSR) - The Standard SPA
这是我们用 npm create vue@latest
创建项目时的默认模式。
- 技术组合: Vue 3 + Vite
- Nuxt 的角色: Nuxt 也可以配置成纯 CSR 模式 (
ssr: false
),但通常我们用更轻量的Vue + Vite
组合来做。
工作流程
开发时 (
npm run dev
):- Vite 启动一个开发服务器。
- 当浏览器请求页面时,Vite 返回一个几乎为空的
index.html
,里面引用了main.js
。 - 浏览器请求
main.js
,Vite 拦截请求,即时编译 Vue 单文件组件(.vue
),然后返回给浏览器。这个过程非常快,实现了无与伦比的热更新(HMR)。
生产构建 (
npm run build
):- Vite 会将我们所有的 Vue 组件、JS 代码和 CSS 打包、压缩、混淆,生成优化后的静态文件(如
app.a1b2c3.js
),并放入dist
目录。 dist
目录下的index.html
依然是一个空壳,但它引用的是打包后的 JS 文件。
- Vite 会将我们所有的 Vue 组件、JS 代码和 CSS 打包、压缩、混淆,生成优化后的静态文件(如
用户访问:
- 整个
dist
目录被部署到静态服务器或 CDN 上。 - 用户的浏览器下载 HTML 空壳和 JS 文件。
- JS 在浏览器中执行,创建 Vue 应用实例,挂载到
#app
节点,然后通过 API 请求数据,最后渲染出完整的页面。
- 整个
2. 服务器端渲染 (SSR) - The Power of Nuxt
纯 Vue + Vite
手动搭建 SSR 非常复杂,需要自己处理服务器、路由、数据预取、客户端注水等一系列问题。这正是 Nuxt 的核心价值所在。
- 技术组合: Nuxt (内置了 Vue 3 和 Vite)
工作流程
Nuxt 默认就是 SSR 模式。
开发时 (
npm run dev
):- Nuxt 启动一个 Node.js 开发服务器(底层由一个叫
Nitro
的引擎驱动,并集成了 Vite)。 - 当浏览器请求一个页面(如
/products/1
)时: a. 请求到达 Nuxt 服务器。 b. 服务器找到匹配的页面组件 (pages/products/[id].vue
)。 c. 如果在组件中使用了asyncData
或useFetch
,服务器会先执行它们,获取 API 数据。 d. 服务器在内存中运行 Vue,将组件和获取到的数据渲染成完整的 HTML 字符串。 e. 服务器将这个包含内容的 HTML 响应给浏览器。 - Vite 在后台提供了客户端和服务器端代码的热更新。
- Nuxt 启动一个 Node.js 开发服务器(底层由一个叫
生产构建 (
npm run build
):- Vite 会构建出两个版本的包:
- 客户端包 (Client Bundle): 用于在浏览器端进行“注水”(Hydration),让页面变得可交互。
- 服务器包 (Server Bundle): 一个为 Node.js 环境优化的包,用于在服务器上渲染页面。
- Vite 会构建出两个版本的包:
用户访问:
- 整个项目被部署到一个 Node.js 运行环境(如 Vercel, Netlify, 或者你自己的服务器)。
- 流程与开发时类似,服务器接收请求,运行服务器包,生成 HTML 并返回。
3. 静态站点生成 (SSG) - "Pre-rendering" with Nuxt
- 技术组合: Nuxt
工作流程
构建时 (
npx nuxi generate
):- 这个命令会启动一个“爬虫”。
- Nuxt 会遍历你所有的静态路由(如
/
,/about
,/contact
)。 - 对于每一个路由,它会执行一次SSR 过程(包括获取数据)。
- 但它不是将生成的 HTML 发送给浏览器,而是将其保存为一个
.html
文件。 - 最终,它会生成一个包含所有预渲染好的 HTML 文件以及所需 JS/CSS 资源的
dist
目录(或.output/public
)。 - 如果项目中有动态路由(如
/products/[id].vue
),你需要告诉 Nuxt 要为哪些id
生成页面。
用户访问:
- 将生成的静态目录部署到任何静态托管平台(如 GitHub Pages, Netlify, Vercel)。
- 用户的体验和访问一个纯静态网站完全一样,速度极快。
4. 增量静态再生 (ISR) & 混合渲染 - The Nuxt Advantage
这是最能体现 Nuxt 作为全栈框架威力的模式。Vite 和 Vue 自身不提供此功能。
- 技术组合: Nuxt
工作流程
在 Nuxt 中,你不需要为整个应用选择一种模式,而是可以为每一条路由指定不同的渲染策略。这是通过 nuxt.config.ts
中的 routeRules
实现的。
示例 nuxt.config.ts
:
typescript
export default defineNuxtConfig({
routeRules: {
// 规则1: 博客文章页面使用ISR,每60秒重新生成一次
'/blog/**': { isr: 60 },
// 规则2: 后台管理页面是纯客户端渲染(SPA)
'/admin/**': { ssr: false },
// 规则3: "关于我们"页面是纯静态生成(SSG)
'/about': { static: true },
// 规则4: 用户个人中心页面是服务器端渲染(SSR)
'/my/profile': { ssr: true }, // 默认行为,可不写
},
});
- **对于 ISR (
/blog/**
)**: 当用户访问一篇博客文章时,服务器会返回一个缓存的静态版本,如果过期了,则在后台重新生成。 - **对于 CSR (
/admin/**
)**: 当访问后台页面时,Nuxt 服务器的行为就和 Vite 一样,只返回一个 HTML 空壳,所有渲染都在客户端完成。 - 对于 SSG (
/about
): 在构建时,/about
页面会被预渲染成about.html
。 - 对于 SSR (
/my/profile
): 每次请求这个页面,服务器都会实时渲染,确保用户看到的是最新的个人信息。
总结表格
渲染模式 | 主要工具 | Vue 3 角色 | Vite 角色 | Nuxt 角色 |
---|---|---|---|---|
CSR | Vue + Vite | 提供组件和渲染逻辑 | 提供开发服务器和生产打包 | 可选,提供约定和便利性 (ssr: false ) |
SSR | Nuxt | 提供renderToString 能力 | 作为 Nuxt 的底层构建引擎(客户端+服务端双打包) | 核心,提供完整的 SSR 架构和开发体验 |
SSG | Nuxt | 同 SSR | 同 SSR | 核心,在构建时调用 SSR 能力生成静态文件 |
ISR/Hybrid | Nuxt | 同 SSR | 同 SSR | 核心,通过路由规则实现精细化的渲染策略控制 |