应组长的要求写了一个表单hook来控制表单内的操作
其中就包含了正在编辑的时候不允许路由跳转,即编辑的时候不允许离开当前页面。
我查找了一下文档就使用了组件路由守卫
onBeforeRouteLeave
但是我在使用的时候是使用一个弹窗来进行提示的
官网的按理就是一个很简单的返回true/false
onBeforeRouteLeave((to)=>{
if(alert){
return true
}else{
return false
}
})
true表示允许跳转 false表示不允许
但是这是最基本的使用方式,真实的业务场景会更加的复杂一些
比如我目前的就是要求加了一个弹窗进行操作
onBeforeRouteLeave(() => {
if (isCurrentOperatingDocuemntChanged.value) {
showDialog({
title: '提示',
message: '当前变动未保存,离开?',
cancelButtonText: '留在本页',
confirmButtonText: '离开',
closeOnPopstate: false,
showCancelButton: true
}).then(() => {
return true
}).catch(() => {
})
} else {
return true
}
})
这个方式确实可以阻止当前页面的路由跳转,但是之后的路由会被影响 最明显的是使用router.back后会白屏
并且只要在onBeforeRouteLeave里面使用异步函数 或者声明async就会白屏 我测试了很久还是这样 网上也有看到说在onBeforeRouteLeave中使用next,但是我使用next就会报错
onBeforeRouteLeave((to,next)=>{
next()//这里会报错
})
后来同事排查了源码后发现如果在onBeforeRouteLeave使用异步函数 则需要使用next进行跳转 并且onBeforeRouteLeave的属性是导航的。所以回调参数是有三个
onBeforeRouteLeave((to,from,next))
next()//少了from的形参所以出错了
最后的代码是这样的就可以正常实现功能了
onBeforeRouteLeave(async() => {
if (isCurrentOperatingDocuemntChanged.value) {
const isLeave = await confirmIsLeavePageDialog()
return isLeave
} else {
return true
}
})
/**
* 是否确认离开弹窗
*/
async function confirmIsLeavePageDialog() {
try {
await showDialog({
title: '提示',
message: '当前变动未保存,离开?',
cancelButtonText: '留在本页',
confirmButtonText: '离开',
closeOnPopstate: false,
showCancelButton: true
})
return true
} catch {
return false
}
}
官方给出的案例太简单了,并且没有明确的说明在onBeforeRouteLeave中使用异步的问题,记录一下这个问题~