六维教程

Nuxt4 中间件

中间件(Middleware)是路由守卫,在页面跳转前执行一段逻辑。最常见的用途是登录鉴权,未登录用户访问需要登录的页面时自动跳转到登录页。

执行时机

中间件在路由切换前执行,执行顺序:

用户点击链接(或输入地址)
        ↓
  路由中间件执行
        ↓
  页面组件创建
        ↓
  页面显示

中间件中可以用 navigateTo 中断跳转,转向其他页面。SSR 模式下,中间件在服务端和客户端都会执行,未登录用户直接访问 URL 时,服务端就会拦截。

创建中间件

app/middleware/ 目录下创建文件。创建 auth.ts,实现登录守卫:

// app/middleware/auth.ts
export default defineNuxtRouteMiddleware((to) => {
  // 从状态管理读取登录状态,见状态管理篇
  const auth = useState('auth', () => ({ loggedIn: false }))

  // 未登录则跳转到登录页,并带上来源地址
  if (!auth.value.loggedIn) {
    return navigateTo({
      path: '/login',
      query: { redirect: to.fullPath }
    })
  }
})

defineNuxtRouteMiddleware 是 Nuxt 提供的中间件包装器,回调接收 to(目标路由)和 from(来源路由)两个参数。

使用中间件

页面级使用

在需要保护的页面中声明:

<!-- app/pages/dashboard.vue -->
<script setup>
definePageMeta({
  middleware: 'auth'   // 中间件名对应文件名
})
</script>

<template>
  <div>控制台,需要登录</div>
</template>

全局使用

中间件文件名加 .global 后缀,所有路由自动生效:

app/middleware/
├── auth.ts          →  命名中间件,页面按需引用
└── analytics.global.ts  →  全局中间件,所有路由生效
// app/middleware/analytics.global.ts
export default defineNuxtRouteMiddleware(() => {
  // 每个路由切换都会执行,比如埋点统计
  console.log('页面切换了')
})

内联使用

不想单独建文件时,可以直接在 definePageMeta 里写匿名中间件:

<script setup>
definePageMeta({
  middleware: [
    (to) => {
      if (to.path === '/secret') {
        return navigateTo('/')
      }
    }
  ]
})
</script>

完整登录流程示例

一个完整的鉴权闭环由三部分构成:

第一步,中间件读取登录状态:

// app/middleware/auth.ts
export default defineNuxtRouteMiddleware((to) => {
  const auth = useState('auth', () => ({ loggedIn: false, user: null }))

  if (!auth.value.loggedIn && to.path !== '/login') {
    return navigateTo('/login')
  }
})

第二步,登录页保存状态:

<!-- app/pages/login.vue -->
<script setup>
const auth = useState('auth', () => ({ loggedIn: false, user: null }))

async function login() {
  const { data } = await $fetch('/api/login', {
    method: 'POST',
    body: { name: '张三' }
  })
  auth.value = { loggedIn: true, user: data }
  navigateTo('/dashboard')
}
</script>

<template>
  <button @click="login">登录</button>
</template>

第三步,页面声明中间件:

<!-- app/pages/dashboard.vue -->
<script setup>
definePageMeta({
  middleware: 'auth'
})
</script>

现在未登录访问 /dashboard,会被自动带到 /login

中间件速查表

用法 写法 生效范围
命名中间件 app/middleware/auth.ts + 页面 middleware: 'auth' 指定页面
全局中间件 文件名带 .global 后缀 所有路由
内联中间件 definePageMeta 里直接写函数 当前页面
中断跳转 return navigateTo('/login') 条件满足时
放行 什么都不返回 正常导航

提示:登录状态存内存(useState)时,刷新页面会丢失,需要重新登录。真实项目通常配合 Cookie 或服务端会话做持久化,属于进阶话题,本教程不展开。

一句话总结:中间件就是路由守卫,app/middleware/ 建文件,页面用 definePageMeta 声明,navigateTo 控制跳转。

上一篇
Nuxt4 布局系统
下一篇
Nuxt4 页面与组件