人人都会AI编程

自动路由、数据获取、组合式函数

更新时间:2026-07-10

Nuxt 3 通过文件系统路由内置数据获取方法组合式函数三大机制,极大简化了全栈应用的开发流程。开发者无需手动配置路由表,也不用在客户端和服务端之间频繁切换数据请求逻辑——一切由框架约定自动完成。


自动路由:约定即路由

在 Nuxt 3 中,pages/ 目录下的文件结构直接映射为应用路由。你不需要写任何路由配置,Nuxt 会在构建时扫描该目录,自动生成 Vue Router 的完整配置。

pages/
  index.vue          → /
  about.vue          → /about
  users/
    index.vue        → /users
    [id].vue         → /users/:id       (动态路由)

实用要点

  • 动态路由:用方括号 [param] 命名文件,组件内通过 useRoute().params 获取参数值。
  • 嵌套路由:在目录中放入 index.vue 作为父级布局,同级文件即为子路由。
  • 路由元信息:在组件中用 definePageMeta 设置中间件、布局或权限控制。
<!-- pages/users/[id].vue -->
<script setup>
const route = useRoute()
console.log(route.params.id) // 动态参数
</script>

效果
新增一个页面只需在 pages/ 下新增一个 .vue 文件,无需重启服务即可热更新路由。这种零配置的方式消除了“路由配置与文件结构脱节”的常见痛点。


数据获取:服务端与客户端无缝切换

Nuxt 3 提供了四个按需选择的数据获取函数,覆盖 SSR、CSR 和静态生成的典型场景。

| 函数 | 执行时机 | 适用场景 |
|------|---------|----------|
| useFetch | 服务端 + 客户端(可选) | 通用数据请求,自动处理 SSR 序列化 |
| useAsyncData | 服务端 + 客户端(可选) | 需要组合多个请求或精细控制缓存 |
| $fetch | 按调用位置决定 | 事件处理或点击触发的请求(纯客户端) |
| useLazyFetch / useLazyAsyncData | 同源,但不会阻塞页面导航 | 非关键数据的后台加载 |

典型用法:服务端渲染优先,客户端激活复用数据

<!-- pages/posts.vue -->
<script setup>
// 服务端发起请求,客户端激活时复用服务端缓存的数据,不重复请求
const { data: posts, pending, error } = await useFetch('/api/posts')
</script>

Nuxt 会自动在服务端执行 useFetch,将结果序列化到 HTML 中。客户端激活时直接使用该数据,不会再次发起网络请求,避免了“页面一闪而过由客户端重新加载数据”的经典体验问题。如果你需要在交互时才获取数据(如点击按钮),改用 $fetch 即可。

错误处理与加载状态
useFetch 返回 pending(加载中)和 error(错误对象),可以直接在模板中渲染对应的状态界面:

<template>
  <div>
    <p v-if="pending">加载中...</p>
    <p v-else-if="error">加载失败: {{ error.message }}</p>
    <ul v-else>
      <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
    </ul>
  </div>
</template>

刷新数据
调用 refresh() 方法可以主动触发重新拉取数据,适合下拉刷新或条件变动场景。


组合式函数:跨组件复用有状态逻辑

Nuxt 3 深度集成 Vue 3 的组合式 API,并且自带了大量实用的官方组合式函数。它们都是自动导入(Auto Import)的,不需要手动 import,直接使用即可。

常用官方组合式函数

| 函数 | 功能 |
|------|------|
| useRoute() | 获取当前路由对象,包含 paramsquerypath |
| useRouter() | 编程式导航跳转 |
| useHead() | 动态设置 <head> 中的 title、meta 等 SEO 信息 |
| useCookie() | 读写响应式 Cookie(服务端/客户端同构) |
| useState() | 跨组件、跨页面共享的状态(类似全局 Pinia Store 的轻量版) |
| useRuntimeConfig() | 访问运行时配置(环境变量等) |

自定义组合式函数
你可以将可复用的业务逻辑封装在 composables/ 目录下,文件名以 use 开头,Nuxt 会自动全局导入。

// composables/useWindowSize.js
export function useWindowSize() {
  const width = ref(0)
  const height = ref(0)

  function update() {
    width.value = window.innerWidth
    height.value = window.innerHeight
  }

  onMounted(() => {
    update()
    window.addEventListener('resize', update)
  })
  onUnmounted(() => window.removeEventListener('resize', update))

  return { width, height }
}

在任意组件中直接调用 const { width, height } = useWindowSize(),逻辑隔离清晰且零配置注入。


三者的协作:一个真实开发流程

假设你要开发一个博客文章列表页:

  1. 自动路由:在 pages/blog/index.vue 创建文件,路由自动生效 /blog
  2. 数据获取:在 script setup 中用 const { data: articles } = await useFetch('/api/articles') 拉取文章列表,服务端渲染首屏内容。
  3. 状态管理:若需要高亮当前分类,用 useState('activeCategory', () => ref('all')) 存储全局状态,配合 useRoute().query 处理 URL 同步。
  4. 自定义组合式函数:如果多个页面都有“滚动加载更多”的逻辑,封装 useInfiniteScroll() 函数,放在 composables/ 下直接复用。

整个过程你不需要手写路由配置、不用纠结数据是在服务端还是客户端执行,也不用担心全局状态会污染组件。Nuxt 的这套机制让开发者将精力集中在业务功能的实现上,而非框架的拼装细节。