nuxt-中间件
它的主要任务是:在进入页面之前执行代码。 常见的应用场景包括: 权限验证:检查用户是否登录,没登录就踢回登录页。 路由守卫:比如 VIP 视频页面,非会员禁止进入。 埋点统计:记录用户从哪个页面

nuxt-中间件

发布时间:2026-04-21 (1分钟前)

它的主要任务是:在进入页面之前执行代码

常见的应用场景包括:

  • 权限验证:检查用户是否登录,没登录就踢回登录页。
  • 路由守卫:比如 VIP 视频页面,非会员禁止进入。
  • 埋点统计:记录用户从哪个页面跳到了哪个页面。
  • 动态重定向:比如根据用户的语言偏好,自动跳转到/zh/en

Nuxt 提供了三种灵活的配置方式:

类型 文件位置 影响范围 场景举例
全局 (Global) middleware/*.global.ts 所有页面跳转都会触发 统计所有页面的访问量
命名 (Named) middleware/auth.ts 只有指定的页面才会触发 仅在“个人中心”开启登录检查
匿名 (Inline) 写在pages/*.vue 仅该当前页面有效 某个特定页面的临时逻辑

生命周期?

中间件运行的时机非常关键。它发生在路由匹配之后渲染页面之前

  • 首次访问(SSR):你在浏览器输入网址回车,中间件在服务器上运行。
  • 后续跳转(SPA):你在页面点击<NuxtLink>,中间件在浏览器中运行。

命名中间件

创建middleware/auth.ts

export default defineNuxtRouteMiddleware((to, from) => {
  const isLoggedIn = false // 模拟登录状态获取逻辑

  // 如果要去管理页且没登录
  if (to.path.startsWith('/admin') && !isLoggedIn) {
    // 强制跳转到登录页
    return navigateTo('/login')
  }
})

在需要保护的页面里调用

<script setup>
definePageMeta({
  middleware: 'auth' // 告诉 Nuxt:进这个页面前,先让 auth 保安查一下
})
</script>

全局中间件

注意名字要包含global

比如auth.global.ts

export default defineNuxtRouteMiddleware((to, from) => {
    console.log("全局中间件", to.path)
    return
})

一般我们会在全局中间件里面判断用户有没有登录,如果没有登录就直接跳转到登录页面

之前前后端分离的情况下,用户的登录状态是存在pinia里面的,但是在nuxtjs中,我们需要这样做

  1. 先将token存入cookie
// 在 login.vue 或 auth store 中
const token = useCookie('auth-token', {
  maxAge: 60 * 60 * 24 * 7, // 有效期 7 天
})
token.value = 'your-server-token' // 写入后,浏览器和服务器都能读取
  1. 在pinia中同步状态
// stores/auth.ts
export const useAuthStore = defineStore('auth', () => {
  const token = useCookie('auth-token')
  const isLoggedIn = computed(() => !!token.value)

  return { token, isLoggedIn }
})
  1. 在全局中间件里面判断
export default defineNuxtRouteMiddleware((to, from) => {
  const authStore = useAuthStore() // 这里的 Pinia 会自动读取上面的 Cookie

  // 白名单:如果是去登录页,直接放行,防止死循环
  if (to.path === '/login') {
    return
  }

  // 判断是否登录
  if (!authStore.isLoggedIn) {
    // 没登录,重定向到登录页
    return navigateTo('/login')
  }
})

匿名中间件

既然有了全局和命名中间件,为什么还要用匿名的?通常用于以下场景:

  • “仅此一家”的逻辑:某个逻辑只在这一特定页面有用,且永远不会被其他页面复用。
  • 临时快速拦截:比如一个特殊的营销活动页,只在特定时间内需要一个简单的校验,没必要去middleware/ 目录增加文件负担。
  • 强耦合逻辑:逻辑与该页面的业务紧密相关,放在一起更方便维护。
<script setup>
definePageMeta({
  // 这里的匿名函数就是一个中间件
  middleware: [
    function (to, from) {
      const config = useRuntimeConfig()
      const isEventEnded = true // 假设这是从某处获取的逻辑

      if (isEventEnded) {
        // 如果活动结束,禁止进入该页面,直接回首页
        console.log('匿名中间件拦截:活动已结束')
        return navigateTo('/')
      }
    },
    // 你甚至可以同时混合使用“命名中间件”
    'auth' 
  ]
})
</script>

<template>
  <div>
    <h1>超级限时活动页</h1>
  </div>
</template>