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 控制跳转。