Appearance
第13章:Nuxt 进阶配置与优化
1. nuxt.config.ts 进阶配置(服务器配置、构建配置、插件配置)
服务器配置:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
server: {
port: 3000, // 服务器端口
host: '0.0.0.0', // 服务器主机
timing: false, // 禁用服务器计时
https: {
key: './server.key',
cert: './server.crt'
} // HTTPS 配置
}
})构建配置:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
build: {
analyze: true, // 构建分析
transpile: ['@vueuse/core'], // 需要转译的依赖
cssSourceMap: true, // 启用 CSS 源映射
extractCSS: true, // 提取 CSS 到单独的文件
optimization: {
splitChunks: {
chunks: 'all',
automaticNameDelimiter: '.',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
}
})插件配置:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
plugins: [
'~/plugins/axios.ts',
'~/plugins/vue-toast.ts',
{ src: '~/plugins/google-analytics.ts', mode: 'client' } // 仅在客户端加载
]
})路由配置:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
router: {
base: '/app/', // 路由基础路径
extendRoutes(routes, resolve) {
// 扩展路由
routes.push({
name: 'custom',
path: '/custom',
component: resolve(__dirname, 'pages/custom.vue')
})
},
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
}
}
})模块配置:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'@nuxtjs/axios',
'@nuxtjs/tailwindcss',
'@nuxtjs/i18n',
'@pinia/nuxt'
],
axios: {
baseURL: 'https://api.example.com'
},
tailwindcss: {
config: {
theme: {
extend: {
colors: {
primary: '#007bff'
}
}
}
}
},
i18n: {
locales: [
{ code: 'en', iso: 'en-US', name: 'English' },
{ code: 'zh', iso: 'zh-CN', name: '中文' }
],
defaultLocale: 'zh'
}
})2. 性能优化技巧(缓存策略、代码分割、预渲染)
2.1 缓存策略
浏览器缓存:
nginx
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}API 缓存:
typescript
// composables/useCachedData.ts
export function useCachedData(key: string, fetchFn: () => Promise<any>, ttl: number = 3600000) {
const cache = useCookie(`cache_${key}`, {
maxAge: ttl / 1000
})
const data = ref(null)
const loading = ref(false)
const error = ref(null)
async function fetchData() {
loading.value = true
error.value = null
try {
if (cache.value) {
data.value = JSON.parse(cache.value)
} else {
const result = await fetchFn()
data.value = result
cache.value = JSON.stringify(result)
}
} catch (err) {
error.value = err
} finally {
loading.value = false
}
}
fetchData()
return { data, loading, error, refresh: fetchData }
}2.2 代码分割
动态导入:
vue
<template>
<div>
<button @click="loadComponent">Load Component</button>
<div v-if="component">
<component :is="component" />
</div>
</div>
</template>
<script setup>
const component = ref(null)
async function loadComponent() {
const { default: MyComponent } = await import('~/components/MyComponent.vue')
component.value = MyComponent
}
</script>路由级代码分割:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
build: {
optimization: {
splitChunks: {
chunks: 'all',
maxInitialRequests: 20,
maxAsyncRequests: 20,
minSize: 20000,
maxSize: 244000
}
}
}
})2.3 预渲染
静态站点生成:
bash
# 生成静态站点
npm run generate预渲染特定路由:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
generate: {
routes: [
'/',
'/about',
'/contact',
'/posts/1',
'/posts/2'
]
}
})动态路由预渲染:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
generate: {
async routes() {
const { data: posts } = await $fetch('https://api.example.com/posts')
return posts.map(post => `/posts/${post.id}`)
}
}
})2.4 其他性能优化技巧
图片优化:
- 使用适当的图片格式(WebP、AVIF)
- 图片压缩
- 懒加载图片
- 使用 CDN 分发图片
资源优化:
- 最小化 CSS/JS
- 启用 Gzip/Brotli 压缩
- 使用 CDN 分发静态资源
- 减少 HTTP 请求数
代码优化:
- 减少重绘和回流
- 使用虚拟列表处理长列表
- 避免内存泄漏
- 优化组件渲染
3. 环境变量配置(开发环境、生产环境区分)
创建环境变量文件:
txt
# .env
NUXT_PUBLIC_API_BASE=https://api.example.com
NUXT_API_KEY=secret_keytxt
# .env.development
NUXT_PUBLIC_API_BASE=http://localhost:3000/api
NUXT_API_KEY=dev_secret_keytxt
# .env.production
NUXT_PUBLIC_API_BASE=https://api.example.com
NUXT_API_KEY=prod_secret_key在 nuxt.config.ts 中配置:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
public: {
apiBase: process.env.NUXT_PUBLIC_API_BASE || '/api'
},
apiKey: process.env.NUXT_API_KEY
}
})使用环境变量:
vue
<template>
<div>
<h1>API Base: {{ config.public.apiBase }}</h1>
</div>
</template>
<script setup>
const config = useRuntimeConfig()
</script>在服务器端使用:
typescript
// server/api/posts.ts
export default defineEventHandler((event) => {
const config = useRuntimeConfig()
const apiKey = config.apiKey
// 使用 apiKey
return { posts: [] }
})4. 自定义中间件(全局中间件、页面中间件)
4.1 全局中间件
创建 middleware/auth.global.ts:
typescript
// middleware/auth.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
const token = useCookie('token').value
if (!token && to.path !== '/login') {
return navigateTo('/login')
}
if (token && to.path === '/login') {
return navigateTo('/')
}
})4.2 页面中间件
创建 middleware/admin.ts:
typescript
// middleware/admin.ts
export default defineNuxtRouteMiddleware((to, from) => {
const user = useState('user').value
if (!user || !user.roles.includes('admin')) {
return navigateTo('/')
}
})在页面中使用:
vue
<!-- pages/admin/index.vue -->
<template>
<div>
<h1>Admin Panel</h1>
<!-- 内容 -->
</div>
</template>
<script setup>
// 内容
</script>
<script>
export default {
middleware: 'admin'
}
</script>4.3 组合中间件
创建 middleware/guest.ts:
typescript
// middleware/guest.ts
export default defineNuxtRouteMiddleware((to, from) => {
const token = useCookie('token').value
if (token) {
return navigateTo('/')
}
})在页面中使用多个中间件:
vue
<!-- pages/login.vue -->
<template>
<div>
<h1>Login</h1>
<!-- 内容 -->
</div>
</template>
<script setup>
// 内容
</script>
<script>
export default {
middleware: ['guest']
}
</script>5. 模块开发(了解 Nuxt 模块机制,自定义模块)
5.1 Nuxt 模块机制
模块结构:
my-module/
├── package.json
├── src/
│ ├── module.ts
│ └── runtime/
│ ├── plugins/
│ └── composables/
└── tsconfig.json模块定义:
typescript
// src/module.ts
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-module',
version: '1.0.0',
configKey: 'myModule'
},
defaults: {
apiKey: ''
},
setup(options, nuxt) {
// 模块设置
nuxt.options.runtimeConfig.public.myModule = {
apiKey: options.apiKey
}
// 添加插件
nuxt.addPlugin({
src: require.resolve('./runtime/plugins/my-plugin.ts'),
mode: 'client'
})
// 添加 composables
nuxt.addComposable({
name: 'useMyModule',
src: require.resolve('./runtime/composables/useMyModule.ts')
})
}
})5.2 自定义模块示例
创建插件:
typescript
// src/runtime/plugins/my-plugin.ts
import { defineNuxtPlugin } from '#app'
export default defineNuxtPlugin((nuxtApp) => {
// 插件逻辑
nuxtApp.provide('myPlugin', {
hello: () => console.log('Hello from my plugin!')
})
})创建 composable:
typescript
// src/runtime/composables/useMyModule.ts
export function useMyModule() {
const config = useRuntimeConfig()
const apiKey = config.public.myModule.apiKey
function getApiKey() {
return apiKey
}
return {
getApiKey
}
}使用模块:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'./my-module'
],
myModule: {
apiKey: 'your-api-key'
}
})在组件中使用:
vue
<template>
<div>
<h1>My Module</h1>
<button @click="testPlugin">Test Plugin</button>
<p>API Key: {{ apiKey }}</p>
</div>
</template>
<script setup>
const { $myPlugin } = useNuxtApp()
const { getApiKey } = useMyModule()
const apiKey = getApiKey()
function testPlugin() {
$myPlugin.hello()
}
</script>小结
本章介绍了 Nuxt.js 的进阶配置与优化,包括 nuxt.config.ts 进阶配置、性能优化技巧、环境变量配置、自定义中间件和模块开发等内容。通过本章的学习,你应该已经掌握了如何配置和优化 Nuxt.js 应用,以及如何开发自定义模块来扩展 Nuxt.js 的功能。
在接下来的章节中,我们将学习 Nuxt.js 的部署与上线、常见问题与面试题等内容,帮助你进一步提升 Nuxt.js 开发技能。
