Skip to content

第16章:拓展学习方向

1. Nuxt 模块生态(官方模块、第三方模块推荐)

1.1 官方模块

@nuxtjs/axios

  • 基于 Axios 的 HTTP 客户端
  • 支持请求拦截器、响应拦截器
  • 支持代理配置
  • 与 Nuxt 3 兼容

@nuxtjs/tailwindcss

  • 集成 Tailwind CSS
  • 支持自定义配置
  • 自动导入 Tailwind 指令

@nuxtjs/i18n

  • 国际化支持
  • 多语言路由
  • 语言切换
  • 翻译管理

@pinia/nuxt

  • 集成 Pinia 状态管理
  • 自动导入
  • 服务端兼容

@nuxtjs/color-mode

  • 深色模式支持
  • 自动检测系统主题
  • 持久化主题偏好

1.2 第三方模块推荐

nuxt-content

  • 内容管理系统
  • 支持 Markdown、YAML、JSON 等格式
  • 自动生成内容 API
  • 支持内容搜索

nuxt-image

  • 图片优化
  • 响应式图片
  • 图片懒加载
  • 支持多种图片服务

nuxt-seo

  • SEO 优化
  • 自动生成 meta 标签
  • 结构化数据
  • 站点地图

nuxt-schema-org

  • 结构化数据生成
  • 支持 Schema.org 标准
  • 自动集成到页面

nuxt-monaco-editor

  • 集成 Monaco Editor
  • 支持代码编辑
  • 自定义主题

2. 移动端适配(Nuxt + Vant、Nuxt + UnoCSS 开发移动端)

2.1 Nuxt + Vant

安装 Vant

bash
# 使用 npm
npm install vant

# 使用 pnpm
pnpm add vant

# 使用 yarn
yarn add vant

配置 Vant

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@vant/nuxt'
  ],
  vant: {
    // 配置选项
  }
})

使用 Vant 组件

vue
<template>
  <div>
    <van-button type="primary">Primary Button</van-button>
    <van-cell title="Cell" value="Content" />
    <van-list
      v-model:loading="loading"
      :finished="finished"
      finished-text="没有更多了"
      @load="onLoad"
    >
      <van-cell v-for="item in list" :key="item" :title="item" />
    </van-list>
  </div>
</template>

<script setup>
const list = ref([])
const loading = ref(false)
const finished = ref(false)

function onLoad() {
  setTimeout(() => {
    for (let i = 0; i < 10; i++) {
      list.value.push(`item ${list.value.length + 1}`)
    }
    loading.value = false
    if (list.value.length >= 40) {
      finished.value = true
    }
  }, 1000)
}
</script>

2.2 Nuxt + UnoCSS

安装 UnoCSS

bash
# 使用 npm
npm install unocss

# 使用 pnpm
pnpm add unocss

# 使用 yarn
yarn add unocss

配置 UnoCSS

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@unocss/nuxt'
  ],
  unocss: {
    // 配置选项
  }
})

使用 UnoCSS

vue
<template>
  <div class="flex flex-col items-center justify-center min-h-screen bg-gray-100">
    <h1 class="text-2xl font-bold text-center text-blue-600">Hello UnoCSS</h1>
    <button class="mt-4 px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition-colors">
      Click Me
    </button>
  </div>
</template>

<script setup>
// 内容
</script>

2.3 移动端适配技巧

响应式设计

  • 使用媒体查询
  • 使用相对单位(rem、em、vw、vh)
  • 使用 flexbox 和 grid 布局

触摸优化

  • 增大点击区域
  • 优化触摸事件
  • 避免使用 hover 效果

性能优化

  • 图片懒加载
  • 组件懒加载
  • 减少 HTTP 请求

PWA 支持

  • 配置 PWA manifest
  • 添加 Service Worker
  • 支持离线访问

3. TypeScript 与 Nuxt(类型定义、接口约束,进阶必备)

3.1 类型定义

创建类型文件

typescript
// types/index.ts
export interface Post {
  id: number
  title: string
  content: string
  author: string
  date: string
}

export interface User {
  id: number
  name: string
  email: string
  role: string
}

在组件中使用类型

vue
<template>
  <div>
    <h1>{{ post.title }}</h1>
    <p>{{ post.content }}</p>
    <p>Author: {{ post.author }}</p>
    <p>Date: {{ post.date }}</p>
  </div>
</template>

<script setup lang="ts">
import type { Post } from '~/types'

const route = useRoute()
const { data: post } = useAsyncData<Post>(`post-${route.params.id}`, () => {
  return $fetch(`/api/posts/${route.params.id}`)
})
</script>

3.2 接口约束

API 接口类型

typescript
// types/api.ts
export interface ApiResponse<T> {
  code: number
  message: string
  data: T
}

export interface LoginRequest {
  email: string
  password: string
}

export interface LoginResponse {
  token: string
  user: User
}

使用接口约束

typescript
// composables/useApi.ts
import type { ApiResponse, LoginRequest, LoginResponse } from '~/types/api'

export function useApi() {
  async function login(data: LoginRequest): Promise<ApiResponse<LoginResponse>> {
    return $fetch('/api/auth/login', {
      method: 'POST',
      body: data
    })
  }
  
  return {
    login
  }
}

3.3 TypeScript 配置

tsconfig.json

json
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["**/*.ts", "**/*.d.ts", "**/*.tsx", "**/*.vue"],
  "references": [{ "path": "./.nuxt/tsconfig.json" }]
}

类型声明文件

typescript
// types/vue-shim.d.ts
declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

4. 服务端接口开发(Nuxt 内置服务器接口,无需单独搭建后端)

4.1 基本 API 接口

创建 API 接口

typescript
// server/api/posts.ts
export default defineEventHandler(async (event) => {
  const query = getQuery(event)
  const page = parseInt(query.page as string) || 1
  const limit = parseInt(query.limit as string) || 10
  
  // 模拟数据
  const posts = [
    {
      id: 1,
      title: 'Getting Started with Nuxt.js',
      content: 'Learn the basics of Nuxt.js',
      author: 'John Doe',
      date: '2024-01-01'
    },
    {
      id: 2,
      title: 'Understanding Vue 3 Composition API',
      content: 'Explore the new Composition API in Vue 3',
      author: 'Jane Smith',
      date: '2024-01-02'
    }
  ]
  
  return {
    code: 200,
    message: 'Success',
    data: {
      posts,
      total: posts.length
    }
  }
})

创建动态 API 接口

typescript
// server/api/posts/[id].ts
export default defineEventHandler(async (event) => {
  const id = event.context.params?.id
  
  // 模拟数据
  const posts = [
    {
      id: 1,
      title: 'Getting Started with Nuxt.js',
      content: 'Learn the basics of Nuxt.js',
      author: 'John Doe',
      date: '2024-01-01'
    },
    {
      id: 2,
      title: 'Understanding Vue 3 Composition API',
      content: 'Explore the new Composition API in Vue 3',
      author: 'Jane Smith',
      date: '2024-01-02'
    }
  ]
  
  const post = posts.find(p => p.id === parseInt(id))
  
  if (!post) {
    throw createError({
      statusCode: 404,
      message: 'Post not found'
    })
  }
  
  return {
    code: 200,
    message: 'Success',
    data: post
  }
})

4.2 数据库集成

安装数据库

bash
# 使用 npm
npm install prisma

# 使用 pnpm
pnpm add prisma

# 使用 yarn
yarn add prisma

初始化 Prisma

bash
npx prisma init

配置 Prisma

prisma
// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String
  author    String
  date      DateTime @default(now())
}

生成 Prisma 客户端

bash
npx prisma generate

使用 Prisma

typescript
// server/api/posts.ts
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export default defineEventHandler(async (event) => {
  const posts = await prisma.post.findMany()
  return {
    code: 200,
    message: 'Success',
    data: {
      posts,
      total: posts.length
    }
  }
})

4.3 中间件与认证

创建认证中间件

typescript
// server/middleware/auth.ts
export default defineEventHandler(async (event) => {
  const token = event.node.req.headers.authorization?.split(' ')[1]
  
  if (!token) {
    throw createError({
      statusCode: 401,
      message: 'Unauthorized'
    })
  }
  
  // 验证 token
  // 这里可以使用 JWT 等库进行验证
  
  // 将用户信息添加到事件上下文
  event.context.user = { id: 1, name: 'John Doe' }
})

使用中间件

typescript
// server/api/protected.ts
export default defineEventHandler(async (event) => {
  // 从上下文获取用户信息
  const user = event.context.user
  
  return {
    code: 200,
    message: 'Success',
    data: {
      user
    }
  }
})

小结

本章介绍了 Nuxt.js 的拓展学习方向,包括 Nuxt 模块生态、移动端适配、TypeScript 与 Nuxt 以及服务端接口开发等内容。通过本章的学习,你应该已经了解了如何扩展 Nuxt.js 的功能,以及如何使用 Nuxt.js 构建更复杂的应用。

在接下来的章节中,我们将学习 Nuxt.js 的学习资源推荐,帮助你找到更多学习材料和社区资源。

© 2026 编程马·菜鸟教程 版权所有