# nuxt4
**Repository Path**: dingyi1399/nuxt4
## Basic Information
- **Project Name**: nuxt4
- **Description**: nuxt4-project
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 3
- **Created**: 2025-12-24
- **Last Updated**: 2025-12-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 🎯 Nuxt.js 面试题大全
> 全面的 Nuxt.js 面试准备指南,包含基础、进阶和高级题目
## 📚 目录
- [基础题](#基础题)
- [SSR 相关](#ssr-相关)
- [路由与页面](#路由与页面)
- [数据获取](#数据获取)
- [性能优化](#性能优化)
- [环境变量与配置](#环境变量与配置)
- [部署相关](#部署相关)
- [实战场景题](#实战场景题)
- [代码题](#代码题)
---
## 基础题
### 1. 什么是 Nuxt.js?它解决了什么问题?
**答案:**
Nuxt.js 是一个基于 Vue.js 的服务端渲染(SSR)框架,它解决了以下问题:
1. **SEO 问题**:传统 SPA 应用对 SEO 不友好,Nuxt 通过 SSR 生成完整的 HTML
2. **首屏性能**:直接返回渲染好的 HTML,提升首屏加载速度
3. **开发复杂度**:提供了约定式的目录结构和自动路由生成
4. **配置繁琐**:内置了 Webpack、Babel、Vue Router 等配置
5. **代码组织**:规范化的项目结构,降低团队协作成本
**核心特性:**
- 服务端渲染(SSR)
- 静态站点生成(SSG)
- 自动路由
- 自动代码分割
- 强大的中间件系统
---
### 2. Nuxt 的渲染模式有哪些?分别适用于什么场景?
**答案:**
Nuxt 支持 3 种渲染模式:
#### 1️⃣ SSR(服务端渲染)
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true // 默认值
})
```
**适用场景:**
- 需要 SEO 的网站(电商、博客、新闻)
- 需要快速首屏的应用
- 内容频繁更新的网站
**优势:** SEO 友好、首屏快
**劣势:** 服务器压力大
---
#### 2️⃣ SPA(单页应用)
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
ssr: false
})
```
**适用场景:**
- 管理后台
- 不需要 SEO 的内部系统
- 交互复杂的应用
**优势:** 服务器压力小、开发简单
**劣势:** SEO 差、首屏慢
---
#### 3️⃣ SSG(静态站点生成)
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true
})
// 构建时生成静态文件
// npm run generate
```
**适用场景:**
- 内容不经常变化的网站(文档、博客)
- 对性能要求极高的场景
- 可以部署到 CDN
**优势:** 性能最佳、成本低
**劣势:** 内容更新需要重新构建
---
### 3. Nuxt 的目录结构是怎样的?各个目录的作用是什么?
**答案:**
```
nuxt-app/
├── app/ # Nuxt 4 的应用目录
│ ├── pages/ # 页面目录(自动生成路由)
│ ├── components/ # 组件目录(自动导入)
│ ├── layouts/ # 布局目录
│ ├── middleware/ # 中间件目录
│ ├── plugins/ # 插件目录
│ ├── composables/ # 组合式函数目录(自动导入)
│ ├── utils/ # 工具函数目录(自动导入)
│ ├── assets/ # 需要处理的资源(CSS、图片等)
│ └── app.vue # 应用根组件
├── public/ # 静态资源(直接访问)
├── server/ # 服务端代码
│ ├── api/ # API 路由
│ ├── routes/ # 服务端路由
│ └── middleware/ # 服务端中间件
├── nuxt.config.ts # Nuxt 配置文件
└── package.json
```
**重点说明:**
- `pages/` 目录自动生成路由
- `components/` 目录组件自动导入,无需手动 import
- `server/api/` 自动创建 API 端点
- `public/` 中的文件可以直接通过 `/` 访问
---
## SSR 相关
### 4. 解释 SSR 的工作原理,以及为什么它对 SEO 更好?
**答案:**
#### SSR 工作流程:
**传统 CSR(客户端渲染):**
```
1. 浏览器请求 →
2. 返回空 HTML ⬇️
3. 下载 JS →
4. 执行 JS →
5. 请求数据 →
6. 渲染页面 ✅
```
**SSR(服务端渲染):**
```
1. 浏览器请求 →
2. 服务器执行 Vue 代码 →
3. 服务器获取数据 →
4. 服务器渲染 HTML →
5. 返回完整 HTML ✅
6. JS 激活(Hydration)
```
#### 为什么 SSR 对 SEO 更好?
**核心原因:搜索引擎爬虫不执行 JavaScript**
**CSR 的问题:**
```html
```
**SSR 的优势:**
```html
商品列表
无线耳机 Pro Max
价格:¥1299
```
**验证方法:**
- 右键"查看网页源代码"
- CSR:看到空的 div
- SSR:看到完整内容
---
### 5. 什么是 Hydration(水合)?为什么需要它?
**答案:**
#### 什么是 Hydration?
Hydration 是指在服务端渲染的 HTML 基础上,在客户端"激活" Vue 应用的过程。
#### 过程:
```
1. 服务端渲染 HTML(静态内容)
↓
2. 浏览器显示 HTML(用户看到内容)
↓
3. 下载 JavaScript
↓
4. Vue 接管 DOM(Hydration)
↓
5. 添加事件监听、响应式等交互功能
```
#### 代码示例:
```vue
```
**执行过程:**
1. 服务端渲染:生成 `` HTML
2. 浏览器显示:用户立即看到按钮
3. Hydration:Vue 接管,添加 `@click` 事件监听
4. 可交互:用户点击后 count 会增加
#### 为什么需要 Hydration?
1. **保持首屏性能**:用户不用等 JS 加载就能看到内容
2. **添加交互功能**:让静态 HTML 变成可交互的 Vue 应用
3. **避免重复渲染**:复用服务端生成的 DOM,不重新创建
#### 常见问题:Hydration Mismatch
```vue
{{ window.innerWidth }}
{{ window.innerWidth }}
```
---
### 6. process.server 和 process.client 的作用是什么?
**答案:**
这两个环境变量用于**区分代码运行环境**。
#### 使用场景:
```typescript
// 只在服务端执行
if (process.server) {
console.log('这段代码在服务端执行')
// 可以访问 Node.js API
// 可以读取环境变量
// 可以访问数据库
}
// 只在客户端执行
if (process.client) {
console.log('这段代码在浏览器执行')
// 可以访问 window、document
// 可以使用 localStorage
// 可以监听浏览器事件
}
```
#### 实际应用:
**1. 避免服务端访问浏览器 API:**
```vue
```
**2. 服务端特定逻辑:**
```typescript
if (process.server) {
// 服务端日志
console.log('服务端接收请求:', event.path)
// 读取服务端配置
const config = useRuntimeConfig()
// 访问数据库
const data = await db.query()
}
```
**3. 条件性导入:**
```typescript
// 只在客户端导入
if (process.client) {
const chart = await import('chart.js')
}
```
---
## 路由与页面
### 7. Nuxt 的自动路由是如何工作的?
**答案:**
Nuxt 根据 `pages/` 目录结构**自动生成路由**。
#### 基础路由:
```
pages/
├── index.vue → /
├── about.vue → /about
└── contact.vue → /contact
```
#### 动态路由:
```
pages/
├── posts/
│ └── [id].vue → /posts/:id
└── users/
└── [name].vue → /users/:name
```
**访问参数:**
```vue
```
#### 嵌套路由:
```
pages/
├── parent.vue
└── parent/
├── child1.vue → /parent/child1
└── child2.vue → /parent/child2
```
**parent.vue:**
```vue
父页面
```
#### 可选参数:
```
pages/
└── [[slug]].vue → / 和 /:slug 都匹配
```
#### 匹配所有路由:
```
pages/
└── [...slug].vue → 匹配所有路径
```
---
### 8. 如何在 Nuxt 中实现页面切换动画?
**答案:**
Nuxt 提供了多种方式实现页面切换动画。
#### 方法 1:全局动画(nuxt.config.ts)
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
app: {
pageTransition: {
name: 'page',
mode: 'out-in'
}
}
})
```
```css
/* app.vue 或全局 CSS */
.page-enter-active,
.page-leave-active {
transition: all 0.3s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
transform: translateY(20px);
}
```
#### 方法 2:单页面自定义动画
```vue
```
#### 方法 3:使用 JavaScript 钩子
```vue
```
---
## 数据获取
### 9. useFetch 和 $fetch 有什么区别?什么时候用哪个?
**答案:**
这是面试高频题!理解它们的区别很重要。
#### 对比表格:
| 特性 | useFetch | $fetch |
|------|----------|--------|
| **类型** | 组合式函数 | 普通函数 |
| **SSR 支持** | ✅ 自动支持 | ⚠️ 需手动处理 |
| **响应式** | ✅ 返回 ref | ❌ 返回普通值 |
| **使用位置** | setup 顶层 | 任何地方 |
| **重复请求** | ✅ 自动去重 | ❌ 不去重 |
| **数据缓存** | ✅ 自动缓存 | ❌ 不缓存 |
#### useFetch(推荐用于组件)
```vue
加载中...
错误:{{ error.message }}
{{ data }}
```
#### $fetch(用于事件处理)
```vue
```
#### 使用场景总结:
**使用 useFetch:**
- ✅ 页面/组件加载时获取数据
- ✅ 需要 SSR 支持
- ✅ 需要响应式数据
- ✅ 需要 loading、error 状态
**使用 $fetch:**
- ✅ 按钮点击等用户交互
- ✅ 在服务端 API 中调用外部接口
- ✅ 在工具函数中
- ✅ 不需要响应式的场景
---
### 10. useAsyncData 和 useFetch 有什么区别?
**答案:**
`useFetch` 其实是 `useAsyncData` 的语法糖。
#### useFetch
```typescript
// 简单场景
const { data } = await useFetch('/api/users')
```
#### useAsyncData(更灵活)
```typescript
// 复杂场景、自定义逻辑
const { data } = await useAsyncData('users', async () => {
// 可以执行任何异步操作
const users = await $fetch('/api/users')
const posts = await $fetch('/api/posts')
// 可以处理数据
return {
users: users.filter(u => u.active),
posts
}
})
```
#### 实际等价关系:
```typescript
// 这两个是等价的
await useFetch('/api/users')
await useAsyncData('users', () => $fetch('/api/users'))
```
#### 什么时候用 useAsyncData?
**1. 需要组合多个请求:**
```typescript
const { data } = await useAsyncData('dashboard', async () => {
const [users, posts, stats] = await Promise.all([
$fetch('/api/users'),
$fetch('/api/posts'),
$fetch('/api/stats')
])
return { users, posts, stats }
})
```
**2. 需要数据处理:**
```typescript
const { data } = await useAsyncData('processed-data', async () => {
const raw = await $fetch('/api/data')
// 复杂的数据处理逻辑
return processData(raw)
})
```
**3. 自定义缓存键:**
```typescript
const route = useRoute()
const { data } = await useAsyncData(
`post-${route.params.id}`, // 自定义唯一键
() => $fetch(`/api/posts/${route.params.id}`)
)
```
---
## 性能优化
### 11. 如何优化 Nuxt 应用的首屏加载性能?
**答案:**
首屏优化是面试重点!需要从多个角度回答。
#### 1️⃣ 使用 SSR/SSG
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true // 启用 SSR
})
```
**收益:** 首屏时间减少 1-2 秒
---
#### 2️⃣ 并行数据请求
```vue
```
**收益:** 数据加载时间减少 40-60%
---
#### 3️⃣ 图片优化(使用 @nuxt/image)
```bash
npm install @nuxt/image
```
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/image']
})
```
```vue
```
**收益:** 图片体积减少 80-90%
---
#### 4️⃣ 代码分割和懒加载
```vue
```
---
#### 5️⃣ 首屏优先策略
```vue
```
---
#### 6️⃣ 预加载关键资源
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
link: [
// 预连接外部域名
{ rel: 'preconnect', href: 'https://api.example.com' },
// 预加载关键字体
{ rel: 'preload', href: '/fonts/main.woff2', as: 'font' }
]
}
}
})
```
---
#### 7️⃣ 使用骨架屏
```vue
```
**收益:** 用户感知加载时间减少 30%
---
### 12. 如何在 Nuxt 中实现接口缓存?
**答案:**
#### 方法 1:useFetch 自动缓存
```typescript
// 自动缓存(基于 URL)
const { data } = await useFetch('/api/users')
// 第二次调用时会使用缓存
const { data: cached } = await useFetch('/api/users') // 不会重新请求
```
#### 方法 2:自定义缓存键
```typescript
const route = useRoute()
// 使用自定义键
const { data } = await useFetch(
'/api/posts',
{
key: `posts-page-${route.query.page}`, // 自定义缓存键
// 相同的 key 会使用缓存
}
)
```
#### 方法 3:服务端缓存(推荐)
```typescript
// server/api/users.ts
import { cachedEventHandler } from '#nitro'
export default cachedEventHandler(
async (event) => {
// 这个函数的结果会被缓存
const users = await db.getUsers()
return users
},
{
maxAge: 60 * 60, // 缓存 1 小时
getKey: (event) => {
// 自定义缓存键
return 'users-list'
}
}
)
```
#### 方法 4:手动控制刷新
```vue
```
---
## 环境变量与配置
### 15. 如何在 Nuxt 中使用环境变量?
**答案:**
Nuxt 提供了 `runtimeConfig` 来管理环境变量,这是最佳实践。
#### 1. 配置 nuxt.config.ts
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// 私有配置(仅服务端可访问)
apiSecret: '', // 从 NUXT_API_SECRET 环境变量读取
dbUrl: '', // 从 NUXT_DB_URL 环境变量读取
// 公开配置(服务端和客户端都可访问)
public: {
apiBase: '', // 从 NUXT_PUBLIC_API_BASE 读取
siteUrl: 'https://example.com'
}
}
})
```
#### 2. 创建 .env 文件
```bash
# .env
# 私有变量(仅服务端)
NUXT_API_SECRET=my-secret-key-123
NUXT_DB_URL=mongodb://localhost:27017/mydb
# 公开变量(客户端也可访问)
NUXT_PUBLIC_API_BASE=https://api.example.com
```
**命名规则:**
- `NUXT_变量名` → 映射到 `runtimeConfig.变量名`
- `NUXT_PUBLIC_变量名` → 映射到 `runtimeConfig.public.变量名`
#### 3. 在代码中使用
**服务端使用(API、中间件):**
```typescript
// server/api/users.ts
export default defineEventHandler((event) => {
const config = useRuntimeConfig()
// ✅ 可以访问私有配置
const apiSecret = config.apiSecret
const dbUrl = config.dbUrl
// ✅ 也可以访问公开配置
const apiBase = config.public.apiBase
return { ok: true }
})
```
**客户端使用(组件、页面):**
```vue
```
#### 4. 不同环境的配置
```bash
# .env.production(生产环境)
NUXT_PUBLIC_API_BASE=https://api.production.com
# .env.development(开发环境)
NUXT_PUBLIC_API_BASE=http://localhost:3001
# .env.staging(预发布环境)
NUXT_PUBLIC_API_BASE=https://api.staging.com
```
#### 5. 类型安全(TypeScript)
```typescript
// types/runtime-config.d.ts
declare module 'nuxt/schema' {
interface RuntimeConfig {
apiSecret: string
dbUrl: string
}
interface PublicRuntimeConfig {
apiBase: string
siteUrl: string
}
}
export {}
```
#### ⚠️ 重要注意事项
**❌ 不要这样做:**
```typescript
// ❌ 不要直接使用 process.env(不支持 SSR)
const apiKey = process.env.API_KEY
```
**✅ 正确做法:**
```typescript
// ✅ 使用 useRuntimeConfig
const config = useRuntimeConfig()
const apiKey = config.apiSecret
```
**安全性考虑:**
- 敏感信息(密钥、token)只放在私有配置
- 公开配置会被打包到客户端 JS 中,任何人都能看到
- .env 文件不要提交到 Git(添加到 .gitignore)
---
### 16. runtimeConfig、appConfig 和 .env 有什么区别?
**答案:**
这是容易混淆的概念,需要明确区分。
#### 对比表格
| 特性 | runtimeConfig | appConfig | .env |
|------|--------------|-----------|------|
| **用途** | 环境相关配置 | 应用配置 | 环境变量 |
| **更新方式** | 需要重启 | 支持热更新 | 需要重启 |
| **私有数据** | ✅ 支持 | ❌ 全部公开 | - |
| **类型提示** | ✅ 支持 | ✅ 支持 | ❌ 不支持 |
| **使用场景** | API密钥、数据库URL | 主题、功能开关 | 环境变量源 |
#### 1. runtimeConfig - 运行时配置
**适用场景:**
- API 密钥、token
- 数据库连接字符串
- 不同环境的配置(开发/生产)
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
apiSecret: process.env.API_SECRET,
public: {
apiBase: process.env.API_BASE
}
}
})
```
**特点:**
- 支持私有和公开配置
- 通过环境变量覆盖
- 需要重启生效
---
#### 2. appConfig - 应用配置
**适用场景:**
- 主题配置(颜色、字体)
- 功能开关
- 非敏感的应用设置
```typescript
// app.config.ts
export default defineAppConfig({
theme: {
primaryColor: '#667eea',
darkMode: true
},
features: {
enableChat: true,
enableNotifications: false
}
})
```
```vue
```
**特点:**
- 全部公开(客户端可访问)
- 支持 HMR(热更新)
- 不能存储敏感信息
---
#### 3. .env - 环境变量文件
**作用:**
- 存储环境变量
- 作为 runtimeConfig 的数据源
- 不同环境使用不同文件
```bash
# .env
API_SECRET=abc123
NUXT_PUBLIC_API_BASE=http://localhost:3001
```
**特点:**
- 不直接在代码中使用
- 通过 runtimeConfig 间接使用
- 不提交到版本控制
---
#### 使用建议
**存储 API 密钥:**
```typescript
// ✅ 使用 runtimeConfig(私有)
runtimeConfig: {
stripeSecretKey: '' // 从 NUXT_STRIPE_SECRET_KEY 读取
}
```
**存储主题配置:**
```typescript
// ✅ 使用 appConfig
// app.config.ts
export default defineAppConfig({
theme: {
primaryColor: '#667eea'
}
})
```
**存储 API 基础 URL:**
```typescript
// ✅ 使用 runtimeConfig.public
runtimeConfig: {
public: {
apiBase: '' // 从 NUXT_PUBLIC_API_BASE 读取
}
}
```
---
## 部署相关
### 17. Nuxt 应用有哪些部署方式?分别适合什么场景?
**答案:**
Nuxt 支持多种部署方式,根据项目需求选择。
#### 1️⃣ Node.js 服务器部署(SSR)
**适用场景:**
- 需要服务端渲染
- 有 Node.js 运行环境
- 动态内容较多
**部署步骤:**
```bash
# 1. 构建
npm run build
# 2. 输出目录
.output/
├── server/ # 服务端代码
└── public/ # 静态资源
# 3. 启动
node .output/server/index.mjs
```
**使用 PM2 管理:**
```bash
# 安装 PM2
npm install -g pm2
# 启动应用
pm2 start .output/server/index.mjs --name "my-nuxt-app"
# 设置开机自启
pm2 startup
pm2 save
```
**Nginx 反向代理:**
```nginx
# /etc/nginx/sites-available/myapp
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```
---
#### 2️⃣ 静态托管(SSG)
**适用场景:**
- 内容不经常变化
- 想部署到 CDN
- 追求极致性能
**生成静态文件:**
```bash
# 生成静态站点
npm run generate
# 输出目录
.output/public/ # 所有静态文件
```
**部署到 Vercel:**
```bash
# 安装 Vercel CLI
npm i -g vercel
# 部署
vercel
```
**部署到 Netlify:**
```toml
# netlify.toml
[build]
command = "npm run generate"
publish = ".output/public"
```
**部署到 GitHub Pages:**
```yaml
# .github/workflows/deploy.yml
name: Deploy to GitHub Pages
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install
- run: npm run generate
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: .output/public
```
---
#### 3️⃣ Docker 部署
**适用场景:**
- 需要容器化
- 微服务架构
- 云原生部署
**Dockerfile:**
```dockerfile
# Dockerfile
FROM node:18-alpine
WORKDIR /app
# 复制 package.json
COPY package*.json ./
# 安装依赖
RUN npm ci
# 复制源代码
COPY . .
# 构建应用
RUN npm run build
# 暴露端口
EXPOSE 3000
# 启动应用
CMD ["node", ".output/server/index.mjs"]
```
**docker-compose.yml:**
```yaml
version: '3.8'
services:
nuxt-app:
build: .
ports:
- "3000:3000"
environment:
- NUXT_API_SECRET=${API_SECRET}
- NUXT_PUBLIC_API_BASE=${API_BASE}
restart: unless-stopped
```
**构建和运行:**
```bash
# 构建镜像
docker build -t my-nuxt-app .
# 运行容器
docker run -p 3000:3000 \
-e NUXT_API_SECRET=secret \
my-nuxt-app
# 或使用 docker-compose
docker-compose up -d
```
---
#### 4️⃣ Serverless 部署
**适用场景:**
- 流量不稳定
- 追求低成本
- 自动扩展
**部署到 Vercel(自动配置):**
```bash
vercel
```
**部署到 AWS Lambda:**
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'aws-lambda'
}
})
```
**部署到 Cloudflare Pages:**
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-pages'
}
})
```
---
#### 部署方式对比
| 方式 | 成本 | 性能 | 扩展性 | 复杂度 |
|------|------|------|--------|--------|
| Node.js 服务器 | 💰💰 | ⭐⭐⭐ | ⭐⭐ | 中 |
| 静态托管 | 💰 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 低 |
| Docker | 💰💰 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 高 |
| Serverless | 💰 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 低 |
---
### 18. 如何处理生产环境的性能监控和错误追踪?
**答案:**
生产环境需要完善的监控和错误追踪。
#### 1. 错误追踪 - Sentry
**安装:**
```bash
npm install @sentry/vue
```
**配置:**
```typescript
// plugins/sentry.client.ts
import * as Sentry from "@sentry/vue"
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig()
Sentry.init({
app: nuxtApp.vueApp,
dsn: config.public.sentryDsn,
environment: process.env.NODE_ENV,
integrations: [
new Sentry.BrowserTracing({
routingInstrumentation: Sentry.vueRouterInstrumentation(nuxtApp.$router)
}),
new Sentry.Replay()
],
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
})
})
```
**使用:**
```vue
```
---
#### 2. 性能监控 - Google Analytics
```typescript
// plugins/gtag.client.ts
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig()
// 加载 Google Analytics
const script = document.createElement('script')
script.async = true
script.src = `https://www.googletagmanager.com/gtag/js?id=${config.public.gaId}`
document.head.appendChild(script)
window.dataLayer = window.dataLayer || []
function gtag() { dataLayer.push(arguments) }
gtag('js', new Date())
gtag('config', config.public.gaId)
})
```
---
#### 3. 自定义监控
```typescript
// server/middleware/monitor.ts
export default defineEventHandler((event) => {
const start = Date.now()
event.node.res.on('finish', () => {
const duration = Date.now() - start
// 记录慢请求
if (duration > 1000) {
console.warn(`Slow request: ${event.path} took ${duration}ms`)
}
// 发送到监控服务
sendMetric({
path: event.path,
duration,
statusCode: event.node.res.statusCode
})
})
})
```
---
#### 4. 健康检查端点
```typescript
// server/api/health.ts
export default defineEventHandler(() => {
return {
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage()
}
})
```
**配置负载均衡器:**
```nginx
# Nginx 健康检查
upstream nuxt_backend {
server localhost:3000 max_fails=3 fail_timeout=30s;
server localhost:3001 max_fails=3 fail_timeout=30s;
}
server {
location / {
proxy_pass http://nuxt_backend;
# 健康检查
health_check uri=/api/health interval=10s;
}
}
```
---
### 19. 如何优化生产环境的构建体积?
**答案:**
减小构建体积可以提升加载速度。
#### 1. 分析构建体积
```bash
# 分析构建产物
npx nuxi analyze
```
---
#### 2. 按需导入
```typescript
// ❌ 全量导入
import _ from 'lodash'
// ✅ 按需导入
import debounce from 'lodash/debounce'
```
---
#### 3. 移除未使用的依赖
```bash
# 检查未使用的依赖
npx depcheck
# 移除
npm uninstall unused-package
```
---
#### 4. 代码分割
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
vite: {
build: {
rollupOptions: {
output: {
manualChunks: {
// 将大型库单独打包
'vendor': ['vue', 'vue-router'],
'charts': ['chart.js'],
}
}
}
}
}
})
```
---
#### 5. 压缩资源
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
compressPublicAssets: true // 启用 Gzip/Brotli 压缩
}
})
```
---
#### 6. 外部化大型依赖(CDN)
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{ src: 'https://cdn.jsdelivr.net/npm/chart.js', defer: true }
]
}
},
vite: {
build: {
rollupOptions: {
external: ['chart.js']
}
}
}
})
```
---
## 实战场景题
### 13. 如何在 Nuxt 中实现用户认证?
**答案:**
完整的认证流程实现。
#### 1. 创建登录 API
```typescript
// server/api/auth/login.post.ts
export default defineEventHandler(async (event) => {
const { username, password } = await readBody(event)
// 验证用户
const user = await db.findUser(username, password)
if (!user) {
throw createError({
statusCode: 401,
message: '用户名或密码错误'
})
}
// 生成 token
const token = generateToken(user)
// 设置 cookie
setCookie(event, 'auth-token', token, {
httpOnly: true,
secure: true,
maxAge: 60 * 60 * 24 * 7 // 7 天
})
return { user }
})
```
#### 2. 创建认证中间件
```typescript
// server/middleware/auth.ts
export default defineEventHandler((event) => {
const token = getCookie(event, 'auth-token')
if (token) {
// 验证 token
const user = verifyToken(token)
event.context.user = user
}
})
```
#### 3. 受保护的 API
```typescript
// server/api/user/profile.get.ts
export default defineEventHandler((event) => {
const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: '未登录'
})
}
return { profile: user }
})
```
#### 4. 前端路由守卫
```typescript
// middleware/auth.ts
export default defineNuxtRouteMiddleware(async (to, from) => {
const { data: user } = await useFetch('/api/user/profile')
if (!user.value && to.path !== '/login') {
return navigateTo('/login')
}
})
```
#### 5. 使用中间件
```vue
Dashboard 内容
```
---
### 14. 如何处理跨域问题?
**答案:**
Nuxt 中处理跨域有多种方式。
#### 方法 1:通过 Nuxt Server API 代理(推荐)
```typescript
// server/api/proxy/[...].ts
export default defineEventHandler(async (event) => {
const path = event.path.replace('/api/proxy', '')
const target = `https://api.example.com${path}`
return await $fetch(target, {
method: event.method,
headers: event.headers,
body: event.body
})
})
```
使用:
```vue
```
#### 方法 2:配置 Nitro 代理
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
devProxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true
}
}
}
})
```
#### 方法 3:服务端转发
```typescript
// server/api/users.ts
export default defineEventHandler(async () => {
// 在服务端请求,没有跨域问题
const data = await $fetch('https://api.example.com/users')
return data
})
```
---
## 代码题
### 15. 实现一个带分页的商品列表页
**答案:**
```vue
商品列表
加载失败:{{ error.message }}
```
**后端 API:**
```typescript
// server/api/products.ts
export default defineEventHandler((event) => {
const query = getQuery(event)
const page = Number(query.page) || 1
const limit = Number(query.limit) || 8
// 模拟数据
const allProducts = [...Array(100)].map((_, i) => ({
id: i + 1,
name: `商品 ${i + 1}`,
price: Math.floor(Math.random() * 1000) + 100
}))
const start = (page - 1) * limit
const end = start + limit
return {
products: allProducts.slice(start, end),
total: allProducts.length,
page,
limit
}
})
```
---
### 16. 实现一个全局的 Loading 提示
**答案:**
```vue
```
---
## 🎓 面试技巧
### 回答问题的结构:
1. **定义/概念**(是什么)
2. **原理/工作方式**(怎么工作)
3. **使用场景**(什么时候用)
4. **代码示例**(怎么用)
5. **优缺点/注意事项**(陷阱)
### 加分项:
- ✅ 能对比 CSR/SSR/SSG
- ✅ 理解 Hydration
- ✅ 知道性能优化方法
- ✅ 能写出实际代码
- ✅ 了解最新特性(Nuxt 4)
- ✅ 熟悉环境变量最佳实践
- ✅ 了解多种部署方式
- ✅ 有实际项目部署经验
- ✅ 知道 Docker/CI/CD
### 高频考点:
1. ⭐⭐⭐ SSR 原理和 SEO
2. ⭐⭐⭐ useFetch vs $fetch
3. ⭐⭐⭐ 首屏性能优化
4. ⭐⭐⭐ 环境变量使用(runtimeConfig)
5. ⭐⭐ 部署方式选择
6. ⭐⭐ 自动路由机制
7. ⭐⭐ 中间件使用
8. ⭐ Hydration 机制
9. ⭐ Docker 部署
---
## 📚 推荐学习资源
- [Nuxt 官方文档](https://nuxt.com)
- [Nuxt 4 新特性](https://nuxt.com/blog/v4)
- [Vue.js 官方文档](https://vuejs.org)
---
**祝你面试成功!🎉**