NuxtJS 3中如何中止页面导航并实现用户认证重定向?
无Middleware的Nuxt3用户认证重定向方案
问题根源
你直接在<script setup>顶层执行路由跳转时,组件仍处于渲染阶段,DOM操作未完成,路由跳转触发组件卸载会导致Vue的DOM更新逻辑冲突,从而抛出insertBefore异常。
解决方案
1. 登录页重定向逻辑(login.vue)
使用watch监听用户状态变化,确保在响应式状态稳定后执行跳转,避免在组件初始化阶段直接操作路由:
<script setup lang="ts"> const router = useRouter(); const user = useFirebaseUser(); // 监听用户状态,页面加载时立即执行一次检查 watch(user, (currentUser) => { if (currentUser) { // 用replace替换路由,避免历史记录中残留登录页 router.replace('/'); } }, { immediate: true }); interface State { email: string; password: string; } const state: State = reactive({ email: "", password: "", }); async function signIn() { try { await signInUser(state.email, state.password); router.replace("/"); } catch (e) { console.log(e); } } </script> <template> <div> <NuxtLink to="/"><button>go back</button></NuxtLink> <h1>Login in</h1> <form @submit.prevent="signIn"> <input v-model="state.email" type="email" /> <input v-model="state.password" type="password" /> <button type="submit">log in</button> </form> </div> </template>
2. 全局未认证重定向逻辑
在布局组件(如layouts/default.vue)或app.vue中添加状态监听,确保未认证用户访问受保护页面时自动跳转到登录页:
<script setup lang="ts"> const router = useRouter(); const user = useFirebaseUser(); watch(user, (currentUser) => { const currentRoute = router.currentRoute.value; // 排除登录页,避免无限重定向循环 if (!currentUser && currentRoute.path !== '/login') { router.replace('/login'); } }, { immediate: true }); </script> <template> <slot /> </template>
方案优势
- 利用Vue响应式监听,自动捕捉用户登录/登出状态变化
- 避免组件渲染阶段的DOM操作冲突
- 无需依赖Nuxt Middleware,规避Firebase与Nuxt3的兼容问题
内容的提问来源于stack exchange,提问作者ThomasG2201
相关产品推荐
相关产品推荐

