求解:onBeforeRouteLeave 钩子影响输入框无法聚焦的原因?
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 钩子中添加一个异步的聚焦操作。例如:
// B 页面
onMounted(async () => {
await nextTick()
inputRef.value?.focus()
})
这样,在 A 页面跳转到 B 页面时,输入框应该能够自动聚焦。
回答:
inputRef.value 的确不存在,或者说,不在DOM 中存在。
所以 focus 就无效了。
可以写成
setTimeout 包一下
以上是 求解:onBeforeRouteLeave 钩子影响输入框无法聚焦的原因? 的全部内容, 来源链接: utcz.com/p/934036.html