vue3 技术栈,A 页面组件销毁时,会执行 onBeforeRouteLeave 钩子函数:
onBeforeRouteLeave(() => {
const confirmed = window.confirm('是否退出?')
if (!confirmed) return false
})
弹出弹框,点击确认按钮,跳转 B 页面。B 页面有一按钮,点击按钮,弹出 ant-design-vue 的 modal 组件,弹窗内有一输入框,需做到输入框自动聚焦,我的代码如下:
// ...
await nextTick()
inputRef.value?.focus()
// ...
// inputRef 表示 input 输入框的 ref
实际情况是输入框无法自动聚焦,实际情况 B 页面刷新后是能聚焦的,说明 B 页面代码没问题。
而将 A 页面 onBeforeRouteLeave 钩子改写如下:
onBeforeRouteLeave((to, from, next) => {
modal.confirm({
centered: true,
icon: '',
content: '是否退出?',
okText: '确认',
cancelText: '取消',
onOk() {
next(true)
},
onCancel() {
next(false)
}
})
})
从 A 页面跳转 B 页面,B 页面弹窗内输入框能正常聚焦,ant-design-vue 的 modal.confirm 本质是一个 promise 函数,所以想知道造成现象的原因,望大佬能解惑。B 页面究竟是哪阻塞了,因为我在 B 页面的
await nextTick()
console.log(inputRef.value)
是能打印出 inputRef.value 对象的。onBeforeRouteLeave 钩子下的同步代码为什么会阻塞目标页面的异步代码执行呢?
这个问题是因为 window.confirm 是一个同步的方法,它会阻止浏览器的其他操作,包括输入框的聚焦。而使用 modal.confirm 是异步的,因此它不会阻止浏览器的其他操作。
当你使用 window.confirm 时,浏览器会在等待用户响应时阻塞执行。这意味着,在这个过程中,其他的操作(如输入框聚焦)无法执行。所以,当你从 A 页面跳转到 B 页面时,输入框无法自动聚焦。
而使用 modal.confirm 时,由于它是异步的,浏览器不会阻塞等待用户响应。这样,当你从 A 页面跳转到 B 页面时,输入框能够正常聚焦。
为了解决这个问题,你可以继续使用 modal.confirm,或者在 window.confirm 的情况下,尝试在 B 页面的 mounted 或 onMounted 钩子中添加一个异步的聚焦操作。例如:
这样,在 A 页面跳转到 B 页面时,输入框应该能够自动聚焦。