前言
前几天优化了老项目:刷新后保持当前页、菜单栏保持激活展开状态。如果手动输入路由再回车也可以进行跳转,这就会带来一个严重问题:我们项目是分角色的,不同角色有不同菜单,比如人事有人事的菜单,财务有财务的菜单,在权限没有做完善的情况下,人事直接输入财务的地址是可以看到财务的页面信息,下面纯前端方式解决这个问题。
解决方案
老项目是Vue2.x,所以我们在路由守卫里面拦截即可,如果是React其实方法也差不多,可以在入口文件写逻辑代码。
利用window.performance.navigation.type
performance.navigation.type 该属性返回一个整数值,表示网页的加载来源,可能有以下4种情况:
- 0:网页通过点击链接、地址栏输入、表单提交、脚本操作等方式加载
- 1:网页通过“重新加载”按钮或者location.reload()方法加载
- 2:网页通过“前进”或“后退”按钮加载
- 255:任何其他来源的加载
// 路由守卫登录鉴权
router.beforeEach(function (to, from, next) {
if (localStorage.getItem("Token")) {
next()
// 判断是否根据修改地址栏进行的跳转
let reloadType = null;
try {
reloadType = window.performance.navigation.type;
} catch (err) {
reloadType = 1;
}
if (reloadType === 0 && !from.name && to.path !== "/home") {
console.error("非法改变路由");
next('/home') // 跳转到首页
}
} else {
next('/')
}
})
代码解释: 已经登录后,判断页面刷新type是否为0 且 路由来源是否存在(路由守卫from是来源,如果是直接刷新或者修改url来的 from对象里面值会是空的)且 不是跳转到首页(这层随意)。如果满足以上条件就证明是直接修改url触发的路由跳转,直接next到首页地址就行。
扩展
另一种解决方式是在入口文件写个路由监听(不推荐) :因为滞后了页面切换,实际上已经转到了目标页调取了目标页的接口,再被转到首页的,代码如下:
watch: {
$route: {
immediate: true,
handler(to, from) {
// 页面刷新类型
let reloadType = null;
try {
reloadType = window.performance.navigation.type;
} catch (err) {
reloadType = 1;
}
if (reloadType === 0 && !from && to.path !== "/home") {
this.$router.push({
path: "/home",
});
console.error("非法改变路由");
}
},
},
},