watcheffect 不校验路由,仅响应权限变化触发跳转;需封装校验逻辑,在其中读取路由 meta.allowedroles 与当前角色比对,不合法时 replace 跳转至 /403 或登录页,并用 isredirecting 或 route name 避免循环;它与 router.beforeeach 协同:后者拦截首次访问,前者处理动态权限变更;权限数据需稳定,应监听 computed 的权限字段并加空值 guard。

watchEffect 本身不校验路由,它只响应权限状态变化并触发跳转;真正的校验逻辑必须由你封装好,在 watchEffect 内调用——它负责“听到权限变了,立刻按规则检查当前页面是否还合法”。
监听权限状态变化并实时比对路由元信息
把用户角色、权限列表或登录态作为响应式源(比如从 Pinia store 解构出 currentUser.role 或 permissions),在 setup 中用 watchEffect 包裹校验逻辑:
- 直接读取 router.currentRoute.value.meta.allowedRoles 和当前用户角色
- 若当前路由要求 admin 权限,而用户是 user,则立即 push 到 /403 或登录页
- 务必加 replace: true,避免无效路径堆积在 history 栈中
避免跳转循环和重复执行
watchEffect 每次跳转后都会重新触发,容易陷入“跳转 → 触发 → 再跳转”死循环:
- 跳转前先判断目标路径是否已是当前路径,例如:if (router.currentRoute.value.path !== '/login')
- 用 router.currentRoute.value.name 做精确匹配,比 path 前缀更可靠
- 引入一个 ref 标记 isRedirecting,watchEffect 内部先检查再执行
与 router.beforeEach 协同分工
watchEffect 是“事后响应”,无法拦截首次访问或刷新后的非法进入:
- router.beforeEach 负责首次加载、URL 直输、页面刷新时的强制拦截
- watchEffect 负责权限动态变更后(如后台切换用户、token 续期升权)的即时同步
- 两者共用同一套校验函数,比如 checkRouteAccess(to, user),避免逻辑分散
确保权限数据稳定可追踪
如果权限来自异步接口,需等数据就绪再启动 watchEffect,否则可能因 undefined 触发误跳:
- 用 computed(() => store.currentUser?.permissions) 封装为稳定响应式视图
- 在 watchEffect 开头加 guard:if (!permissions.value || permissions.value.length === 0) return
- 不要监听 loading 状态本身,而是监听最终产出的权限数组或角色字段
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









