项目中遇到一个问题:
当我在/goodList页面上, 地址栏的参数发生过改变,我的路有变化如下:
- /index
- /goodslist?c_id=6661&c_t=3
- /goodslist?c_id=6666&c_t=3
- /goodslist?c_id=5773&c_t=2
这时候如果用户点击浏览器的后退按钮,只是回退参数,而不是回到上一个路由。 回到了:3. /goodslist?c_id=6666&c_t=3
用户体验不佳:点击后退按钮,页面看似没有变化。
我的目的是想回到 1. /index
解决方案:拦截后退操作,当检测到 参数变化 而不是路由变化时,手动导航到上一个路由。
- 使用 popstate 监听历史变化:
因为我的Vue Router版本低,没有this.$router.history.stack, 所以我们手动创建历史栈
在main.js中全局注册,后退操作在 main.js 中集中处理,便于维护
// 自定义历史栈
const historyStack = [];
// 判断两个路由路径是否相同(不包含参数)
function isSamePath(route1, route2) {
return route1.path === route2.path;
}
// 监听路由变化,修改历史栈
router.beforeEach((to, from, next) => {
const routeData = {
path: to.path,
query: to.query,
params: to.params,
hash: to.hash,
};
// 如果栈为空,或者当前路由和栈顶路由路径不同,添加到栈
if (historyStack.length === 0 || !isSamePath(historyStack[historyStack.length - 1], routeData)) {
historyStack.push(routeData); // 新的路由直接添加
} else {
// 如果路径相同,则删除栈中的最后一个路由,再添加新的路由
historyStack.pop();
historyStack.push(routeData);
}
next();
});
// 后退逻辑
function handlePop() {
if (historyStack.length > 1) {
historyStack.pop(); // 弹出当前路径
}
const prevRoute = historyStack[historyStack.length - 1] || { path: '/' };
// 使用完整路由信息进行跳转
router.replace(prevRoute);
console.log('当前历史栈:', historyStack);
}
// 浏览器后退按钮监听
window.addEventListener('popstate', () => {
handlePop();
});
这样就可以实现,点击浏览器的后退按钮时, 回退到和当前路由不同的上一个路由, 而不是上一个参数不同的网址上!