vue3 离开页面时弹框用户确认或取消,以及hooks封装,在其他页面使用
摘录来自
https://www.jianshu.com/p/7b054af5e3d9
先上html
<van-dialog v-model:show="confimShow" title="温馨提示" show-cancel-button>
<p style="color: #484848; text-align: center; margin-top: 10px">
是否确认退出平台?
</p>
<template #footer>
<div class="btn-group flex align-center justify-between">
<button class="cancel" @click="cancel">取消</button>
<button class="confirm" @click="confirm">确认</button>
</div>
</template>
</van-dialog>
这里用到 promise 和 router 和 一个变量来控制
import { onBeforeRouteLeave,useRouter } from "vue-router"; //vue3使用这个钩子
const confimShow = ref(false); //弹框显示
const out = ref(false) //控制下次离开页面时候是否继续弹框
let resolveFn, rejectFn; //保存用户确认和取消 的回调
function cancel() {
rejectFn && rejectFn()
confimShow.value = false
}
function confirm() {
resolveFn && resolveFn()
confimShow.value = false
}
onBeforeRouteLeave(async (to, from, next) => {
if (out.value) {
next() // 如果是true 就不继续弹框
} else {
next(out.value) //为false时候,先中断这次路由跳转
await new Promise((resolve, reject) => {
resolveFn = resolve //分别暴露这个promise的
rejectFn = reject
setTimeout(() => {
confimShow.value = true; //显示是否退出弹框 ,这里一定要开多一个 宏任务,微任务不知道行不行,感兴趣的自己试试,我懒。否则弹框不会显示
}, 20)
}).then(res => { //如果用户点击确认 就设置true 下次不用弹框
out.value = true
router.back() //这里用 push 或者 back 都行。看个人需求
}).catch(err => {})
}
});
封装成hooks的写法如下
import { ref} from "vue";
import { onBeforeRouteLeave,useRouter } from "vue-router"; //vue3使用这个钩子
import { ElMessageBox } from 'element-plus';
export function useLeaveCheck(){
const router=useRouter()
const useCheck=ref(false) // 是否需要路由检测拦截
const canLeave = ref(false) //控制下次离开页面时候是否继续弹框
const showConfirm=()=>{
ElMessageBox.confirm(
'数据未保存,是否仍要离开当前页面?',
'提示',
{
confirmButtonText: '直接离开',
cancelButtonText: '继续编辑',
type: 'warning',
}
).then(() => {
canLeave.value=true
router.back()
}).catch(() => {
console.log('继续编辑')
canLeave.value=false
})
}
const onChange=()=>{
return onBeforeRouteLeave(async (to, from, next)=>{
if(useCheck.value){
if (canLeave.value) {
next() // 如果是true 就不继续弹框
} else {
next(canLeave.value)
showConfirm()
}
}else{
next()
}
});
}
return {
useCheck,
onChange
}
}
具体页面的使用
import { useLeaveCheck } from "@/hooks/leaveCheck";
const {onChange,useCheck}=useLeaveCheck()
onChange()
const cancel=()=>{
useCheck.value=true
//router.push('xxxxx)
}
const submit=()=>{
useCheck.value=false
//router.push('xxxxx)
}