Nuxt监听isAuthenticated未跳转且auth中间件死循环问题排查
问题1:页面Watcher未触发跳转的原因
你的配置项存在拼写错误:imediate是错误写法,正确参数名为immediate(缺少字母m)。拼写错误导致初始化立即执行的配置不生效,只有监听值后续发生变化时才会触发handler,这就是条件判断正确但路由跳转未执行的核心原因。
修正后的页面Watcher代码:
watch: { '$store.state.auth.isAuthenticated': { immediate: true, // 修正拼写错误 deep: false, handler(newVal) { if( !newVal ) this.$router.push({'name': 'login'}); } }, },
问题2:auth中间件死循环的原因
死循环由两个逻辑缺陷共同导致:
watchedStores数组定义在中间件函数内部,每次中间件执行都会初始化新的空数组,watchedStores.pop()永远返回undefined,完全达不到清理旧watcher的效果,每次路由跳转都会新增一个watcher,触发createNavigationGuard的次数会持续叠加store.watch配置了immediate: true,每次新增watcher都会立即执行回调调用createNavigationGuard,如果createNavigationGuard内部包含路由跳转逻辑,就会再次触发中间件执行、新增新的watcher、再次触发跳转,最终形成死循环
中间件修复方案
将watchedStores移到中间件函数外部,变成全局持久化变量,就能正确清理上一次的watcher:
import { createNavigationGuard } from "~/plugins/navigation-guard.js"; // 移到函数外部,全局持久化存储watcher清理函数 const watchedStores = []; const unwatchStore = (unwatch) => { if (typeof unwatch === "function") { unwatch(); } }; export default function (context) { if (process.client) { // 每次执行中间件先清理上一次的watcher unwatchStore(watchedStores.pop()); const unwatch = context.store.watch( (state) => state.auth.isAuthenticated, (isAuthenticated) => { createNavigationGuard(context, isAuthenticated); }, { immediate: true, } ); watchedStores.push(unwatch); } if (process.server) { createNavigationGuard( context, context.store.state.auth.isAuthenticated ); } }
内容的提问来源于stack exchange,提问作者Čamo
相关产品推荐
相关产品推荐

