Nuxt2中全局路由守卫的写法(含Nuxt3写法和变化)
一、在middleware中定义(server端执行)
- 全局middleware中定义
- 在middleware文件夹下新建auth.js文件,在这个文件中,通过上下文对象context.route实现路由拦截
// auth.js文件
import Cookies from 'js-cookie'
const whiteList = ['login', 'home', 'ProductDetails'];
export default function ({ store, route, $axios, redirect, req }) {
console.log('全局中间件执行了');
// 尝试在服务器端获取 Cookies
let auth = null;
if (process.server) {
if (req.headers.cookie) {
auth = req.headers.cookie.split(';').find(c => c.trim().startsWith('Admin-union-Token='));
if (auth) {
auth = auth.split('=')[1];
}
}
} else {
// 在客户端使用 js-cookie 获取
auth = Cookies.get("Admin-union-Token");
}
if (!auth && whiteList.indexOf(route.name) === -1) {
return redirect('/login')
}
}
- 在nuxt.config.js文件的router配置项中引入该中间件
// nuxt.config.js文件
export default {
....
router:{
middleware:['auth']
}
}
- 局部layouts中middleware的定义
// layouts/default.vue(Nuxt 2)
export default {
middleware({ route, redirect }) {
console.log('layout中的middleware执行了');
if (!Cookies.get("Admin-union-Token") && whiteList.indexOf(route.name) === -1) {
return redirect('/login');
}
}
}
Nuxt 2 特点
- 直接通过 this.$route 或 route 访问路由信息。
- 使用 redirect() 方法进行跳转。
- Middleware 可以定义在:
- 布局文件(layouts/*.vue)
- 页面文件(pages/*.vue)
- 独立的 middleware/ 目录文件。
Nuxt 3 的写法
使用中间件(推荐)
在 Nuxt 3 中,路由拦截应优先使用中间件,Nuxt 3 的 middleware 有较大变化,需要单独定义在 middleware/ 目录下,并通过 defineNuxtRouteMiddleware
创建:
// middleware/auth.global.ts(Nuxt 3)
// 全局中间件,文件需放在 middleware/ 目录,.global.ts 后缀表示全局中间件,使用 navigateTo() 替代 redirect()
export default defineNuxtRouteMiddleware((to, from) => {
const authToken = useCookie('Admin-union-Token'); // Nuxt 3 推荐使用 useCookie
const whiteList = ['login', 'home', 'ProductDetails']; // 白名单路由name
if (!authToken.value && !whiteList.includes(to.name as string)) {
return navigateTo('/login');
}
});
Nuxt 3 特点
- 使用 defineNuxtRouteMiddleware 定义中间件。
- 参数变为 to 和 from(对应 Vue Router 的路由对象)。
- 跳转改用 navigateTo()
- 通过 useCookie() 替代直接操作 Cookie(更安全)。
- 全局中间件需以 .global 后缀命名(如 auth.global.ts)。
二、plugin插件中定义(client端执行)
- Nuxt2中,在plugins文件夹下定义route.js文件,在该文件中通过router.beforeEach前置守卫或router.afterEach后置守卫进行拦截;
// plugins/route.js文件:
export default ({ app, redirect }) => {
app.router.afterEach((to, from) => {
if (!Cookies.get("Admin-union-Token") && whiteList.indexOf(to.name) === -1 ) {
return redirect('/login')
}
next()
})
}
Nuxt3中通过插件拦截路由(不推荐)
// plugins/route.client.ts (仅客户端)
// 如果坚持用插件方式(兼容旧项目):
export default defineNuxtPlugin(({ $router }) => {
$router.beforeEach((to) => {
const token = useCookie('Admin-union-Token');
const whiteList = ['login', 'register'];
if (!token.value && !whiteList.includes(to.name as string)) {
return '/login';
}
});
});
注意:
- 文件需加 .client 后缀确保只在客户端运行
- Nuxt 3 默认自动加载插件,无需在 nuxt.config.ts 中配置
- Nuxt2中,在nuxt.config.js配置文件中添加该plugin的配置;
// nuxt.config.js配置文件
export default {
....
plugins: [
{ src: '~/plugins/route/route.js', ssr: false }
],
}
执行顺序:server端>client端