求解: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

回到顶部