龙虎机器人 全局前置守卫常见错误
一、全局前置守卫常见错误
1. 未正确调用next()
这是最常见的错误之一,若忘记在守卫中调用next(),会导致路由导航卡住,页面无法跳转。 错误示例:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
// 忘记调用next(false)或next('/login')
}
// 也忘记调用next()的成功分支
});
现象:点击链接后页面“卡死”,URL不变,控制台无报错,但路由未切换。 正确做法:确保在所有逻辑分支中都调用next(),且仅调用一次。
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
isAuthenticated() ? next() : next('/login');
} else {
next();
}
});
2. 异步操作未等待完成就调用next()
当守卫中存在异步操作(如获取用户信息、校验权限),若未等待异步操作完成就调用next(),会导致逻辑判断失效。 错误示例:
router.beforeEach(async (to, from, next) => {
const user = await fetchUser();
if (user.role !== 'admin') {
next('/forbidden');
}
next(); // 在条件判断外重复调用next()
});
现象:即使用户无权限,仍会跳转到目标页面,因为next()被多次调用,最后一次覆盖了重定向。 正确做法:使用async/await等待异步操作完成,并确保每个逻辑分支都有对应的next()调用。
router.beforeEach(async (to, from, next) => {
try {
const user = await fetchUser();
if (user.role !== 'admin') {
next('/forbidden');
} else {
next();
}
} catch (error) {
console.error(error);
next('/error');
}
});
二、组件内守卫常见错误
1. 守卫定义位置错误
在选项式API中,组件内守卫必须定义在组件选项的根级别,若定义在methods中,守卫函数将不会被调用。 错误示例:
<script>
export default {
methods: {
beforeRouteEnter(to, from, next) {
console.log('不会执行!');
next();
}
}
};
</script>
现象:守卫函数从未被调用,因为Vue Router仅识别直接定义在组件选项根级的守卫方法。 正确做法:将守卫直接定义在组件选项根级别。
<script>
export default {
beforeRouteEnter(to, from, next) {
console.log('组件内守卫执行!');
next();
}
};
</script>
2. 路由参数变化未触发组件更新
当路由参数变化时(如从/user/1到/user/2),组件不会重新创建,若未处理这种情况,会导致数据不更新。 错误现象:页面URL变化,但组件数据未更新。 正确做法:使用beforeRouteUpdate守卫或监听$route对象。
// 方法一:使用beforeRouteUpdate守卫
beforeRouteUpdate(to, from, next) {
this.userId = to.params.id;
this.fetchUserData();
next();
}
// 方法二:监听$route对象
watch: {
'$route'(to, from) {
this.userId = to.params.id;
this.fetchUserData();
}
}
三、路由独享守卫常见错误
1. 守卫未绑定到具体路由
路由独享守卫必须定义在路由配置对象中,若单独定义但未关联到路由,守卫将不会生效。 错误示例:
const routes = [
{
path: '/admin',
component: Admin,
// 忘记添加beforeEnter守卫
}
];
// 单独定义但未关联
function adminGuard(to, from, next) {
if (!isAdmin()) next('/login');
else next();
}
现象:守卫函数存在但未生效,因为未将其赋值给路由配置的beforeEnter属性。 正确做法:将守卫函数直接赋值给路由配置的beforeEnter属性。
const routes = [
{
path: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
isAdmin() ? next() : next('/login');
}
}
];
2. 异步处理不当
路由独享守卫中若存在异步操作,需手动处理异步逻辑,确保在异步操作完成后再调用next()。 错误示例:
beforeEnter: (to, from, next) => {
fetchUserRole().then(role => {
if (role !== 'admin') {
next('/forbidden');
}
});
next(); // 异步操作未完成就调用next()
}
正确做法:在异步操作的回调中调用next(),或使用async/await。
beforeEnter: async (to, from, next) => {
try {
const role = await fetchUserRole();
role === 'admin' ? next() : next('/forbidden');
} catch (error) {
console.error(error);
next('/error');
}
}
四、其他常见错误
1. 全局后置钩子调用next()
全局后置钩子不接受next函数,也不能改变导航,若在其中调用next(),会导致错误。 错误认知:认为全局后置钩子可以通过next()改变导航。 正确认知:全局后置钩子仅在导航完成后执行一些副作用操作,如更新页面标题。
router.afterEach((to, from) => {
document.title = to.meta.title || 'Vue App';
});
2. 重复调用next()
在同一个守卫中多次调用next(),会导致不可预测的导航行为,Vue Router v4会对此发出警告。 错误示例:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
next('/login');
}
next(); // 重复调用next()
});
正确做法:确保每个逻辑分支只调用一次next()。
