【Web前端问题】vue单页应用阻止浏览器后退?

web app 单页应用,是用vue vue-router写的。

有些页面是需要禁止后退的,我把当前页面是否能后退写在了路由元信息meta里面,比如为allowBack。

查到资料 禁止后退的方法是
history.pushState(null, null, location.href)

之前项目用的是vue1.0,解决方法是

1. 在全局的router.beforeEach 里面 判断当前路由的handler里面的allowBack变量是否为false

2. 如果为false 则 history.pushState(null, null, location.href)

现在改用vue2.0, 原来的方法不好使了,

现在的问题是,不知道该把 history.pushState(null, null, location.href) 这段代码放在哪
或者说 各位大神 有没有什么其他的解决方案? 谢谢!!


其实主要的使用场景是这样的,
tabbar点击切换到不同的页面,假如我现在在a页面,点击tabbar到b页面,我不能通过返回键回到a页面,但是能通过点击tabbar去到a页面
图片描述

回答:


今天一搜 网上看到好几篇复制这个答案发的贴子或者文章,
出于我个人的思考 我觉得我还是要表个态(觉得我矫情也好较真也好 略略略~)

1.其实这个答案并不好,甚至是有问题的,
2.而且这个方案 并不是我一个人的成果,然而我之前的回答并没有说明,

啰嗦一下。。
以前去网上搜某种解决方案,发现铺天盖地的都是一样的文章。回去一试,发现是有问题的。。。那种心情。。。
所以也不希望自己的答案带来这种影响。。


自问自答.....
需求是:需要某个路由不能通过浏览器返回,同时不影响相互之间的切换
整理一下解决方法 和 使用方法:

1.在路由配置中给这个路由添加meta信息,比如:

{

path: '/home',

component: xxx,

meta: {allowBack: false}

}

2.在全局的router.beforeEach 函数里面获取allowBack的状态,同时更新vuex的allowBack的值,如:

let allowBack = true    //    给个默认值true

if (to.meta.allowBack !== undefined) {

allowBack = to.meta.allowBack

}

if (!allowBack) {

history.pushState(null, null, location.href)

}

store.dispatch('updateAppSetting', { // updateAppSetting 只是store里面的一个action, 用来改变store里的allowBack的值的,具体怎么改这个值 要根据各位的实际情况而定

allowBack: allowBack

})

这段代码得写在next()的后面

3.接下来就是最核心的了,在app.vue的mounted里面写onpopstate事件:

window.onpopstate = () => {

if (!this.allowBack) { // 这个allowBack 是存在vuex里面的变量

history.go(1)

}

}

最后: 这个不是一个完美方法,在网页上初次会有闪烁,但对于嵌入原生app的网页,就我经过的项目来说还是可以用的。
看评论有很多人不成功,不知道是报错还是没有效果,我已经写得很清楚,实在想不出还有啥能写的了,抱歉了各位

再补充:
关于上面提到的初次闪烁,刚刚又去验证了一下:
在a页面刷新(beforeRouteEnter 中打印 a), // 这里log 打印了一个a
跳转到b页面(beforeRouteEnter 中打印 b,b页面allowBack 为false), // log 打印 b
点击返回键, // 此时log又打印了一个了a和一个b,但是页面还是回到b页面了的,这个过程很快,有时甚至看不到闪烁,可能跟页面的性能和复杂程度有关

随后的操作就没有发现上面的问题了,大家可以试试

回答:

我也遇到类似的问题,使用的解决办法是用vuejs.org/zh/guide/advanced/navigation-guards.html" rel="nofollow">导航守卫,我感觉使用起来会简单一点。

回答:

试试这样看看

//改写返回函数,返回的时候就会触发这个,

//你也可以直接监听浏览器的返回事件,定义一个变量就行了,逻辑跟这个差不多

Router.prototype.goBack = function () {

this.isBack = true

window.history.go(-1)

}

//假如当前页面是b页面,是由a页面点击过来的,现在b页面点击返回键,不能返回到a页面

router.beforeEach( (to, from, next) => {

//一当点击返回键,那么to就是a页面,from就是b页面

if(!from.meta.allowBack){

//进行页面判断,取出history里面之前的url,对这个url进行判断,看他等不等于to这个页面

//因为安全原因,js没法获取history里的url,或者获取麻烦,所以你就要自己来记住url

//就是每进入一个页面,你都去把之前的页面路径存在sessionStorage中

//···判断过程省略

//这里取出,然后对比就可以了

//如果等于的话,直接禁止

//取出结果

var path = sessionStorage.getItem('path');

//这个this我没有实验,应是指向router

if(path == to.path && this.isBack){

//什么都不做,只要不执行next方法,路由是不会跳的

this.isBack = false;

} else {

//否则的话,就代表不是点击的返回键,该跳转就跳转

//这里也存储

sessionStorage.setItem('path',from.path);

this.isBack = false;

next()

}

}else{

//在这里存储

sessionStorage.setItem('path',from.path);

this.isBack = false;

next();

}

});

回答:

你是不是教程没看完就进入生产环境了?
实现你这种tab页需求直接用 router replace 就完事了

<router-link to="home" replace>主页</router-link>

<router-link to="user" replace>个人</router-link>

<router-link to="message" replace>消息</router-link>

以上是 【Web前端问题】vue单页应用阻止浏览器后退? 的全部内容, 来源链接: utcz.com/a/144205.html

回到顶部