开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
前言
以前不知道vue3的vue-router 的组件守卫钩子这么好用,在这边记录一下自己遇到的关于h5再带返回按钮的bug问题。。。
一.问题整理
- 点返回键需要给出提示信息确认后再返回上一页
- 遇到页面route传参,点击返回会留下记录返回上一页的情况
1:点返回键需要给出提示信息确认后再返回上一页
之前百度搜到最多的答案就是用如下这种方式:
const backChange = (e) => {
console.log('1', window.history.length)
Dialog.confirm({
title: '提示',
message: '您的合同还未提交,是否确认离开?\n(离开后编辑的信息将不会保存)',
confirmButtonText: '确认离开',
cancelButtonText: '我再想想'
})
.then(() => {
// on confirm
console.log('2', window.history.length)
window.removeEventListener('popstate', backChange, false)
// window.location.href = back.value
// window.history.back()
router.go(-2)
})
.catch((e) => {
// on cancel
history.pushState(null, null, location.href)
window.removeEventListener('popstate', backChange, false)
window.addEventListener('popstate', backChange, false)
})
}
onMounted(() => {
if (window.history && window.history.pushState) {
var state = {
title: 'title',
url: ''
}
history.pushState(state, 'title', '')
window.addEventListener('popstate', backChange, false)
}
})
onUnmounted(() => {
window.removeEventListener('popstate', backChange, false)
})
这种方式总结一句话:真麻烦,代码量多还需要计算回退的次数,这边建议大家看看就好,掘金上有一个文章专门有讲到怎么计算的,我贴个链接:
单页应用巧用history.go()、history.length返回到历史指定页面 - 掘金
最好的方式如下:
onBeforeRouteLeave(async (to, from) => {
if (to.path.indexOf('/xxx/index') > -1) {
try {
return await backChange()
} catch (e) {
return false
}
}
})
const backChange = () => {
return new Promise((resolve, reject) => {
Dialog.confirm({
title: '提示',
message: '您的合同还未提交,是否确认离开?\n(离开后编辑的信息将不会保存)',
confirmButtonText: '确认离开',
cancelButtonText: '我再想想',
closeOnPopstate: false //这个必须加上不然不起作用
})
.then(() => {
resolve()
})
.catch((e) => {
reject()
})
})
}
是不是美滋滋的方法!建议大家好好看看vue的路由,基础不好碰到的坑就会多多!
提示 : 像onBeforeRouteLeave这个方法在组件v-if内切换不同的子组件,h5自带返回的情况也可以使用!
2:遇到页面route传参,点击返回会留下记录返回上一页的情况
遇到这种我是因为遇到这样的一个业务场景比如:页面a->b->c ,a到b需要传参数,b->c路由也需要传参数,但是最后c->b->a 返回的时候,c->b传参数导致,路由会增加新的记录,这边你会说用replace来改变,但是你可知道,b->c ,c->b这两个页面都用到replace的话,会导致我c返回直接返回a的情况,所以问题又来了,该怎么解决呢,附上代码:注意记得b->c 用push ,c->b用replace
onBeforeRouteUpdate(to => {
router.go(-1)
})
简简单单一行代码搞定!
当然也可以按照官网另外一种方法,对同一个组件中参数的变化做出响应的话,你可以简单地 watch$route对象上的任意属性,就是$route.params或$route.query:
created() {
this.$watch(
() => this.$route.params,
(toParams, previousParams) => {
// 对路由变化做出响应...
}
)
},