Vue:如何在单击按钮时调用 .focus()
Vue: How to call .focus() on button click
我昨天才开始用 vue.js
编码,我不知道如何在文本框上 "focus" 不使用 "traditional" JS 方式,即 document.getElementById('myTextBox').focus()
.
最初,我的文本框是隐藏的。我有一个 "Start" 按钮,当用户点击它时,会显示文本框,我想在那里设置 focus
,可以这么说。我已经尝试使用 ref
,但无济于事(请参阅下面的代码)。
HTML:
<input id="typeBox" ref="typeBox" placeholder="Type here..." />
Javascript
export default {
name: 'game',
methods: {
startTimer () {
setTimeout(function () { /* .focus() won't work without this */
/* ugly and not recommended */
// document.getElementById('typeBox').focus()
/* Throws the error: Cannot read property 'typeBox' of undefined */
this.$refs.typeBox.focus()
// ... any other options?
// ...
}, 1)
}
} /* END methods */
} /* END export default */
有人知道怎么做吗?请帮忙。
更新:
在 input
上添加 autofocus
可以在页面加载后立即聚焦。但是在我的应用程序中,需要在输入字段上多次 "refocus" 而不重新加载页面,这就是为什么我需要一种方法来调用 .focus()
.
setTimeout
函数中this
的值将被设置为window
对象,因为它是一段时间后执行的回调函数,它已经失去了[的范围=12=] 从调用函数的地方动态设置的关键字。
箭头函数不绑定它自己的 this
值。
startTimer () {
setTimeout(() => {
this.$refs.typeBox.focus()
}, 1)
}
或
startTimer () {
const self = this;
setTimeout(function () {
self.$refs.typeBox.focus()
}, 1)
}
在此分享解决方案,以防有人遇到同样的问题...
在高级程序员的帮助下,我终于弄明白了。我也能够一路消除 setTimeout
,使用它的 vue
版本 nextTick()
.
正确的JS代码:
startTimer () {
this.$nextTick(() => {
// this won't work because `this.$refs.typeBox` returns an array
// this.$refs.typeBox.focus()
//this one works perfectly
this.$refs.typeBox[0].focus()
})
} /* END startTimer */
解释:
当我使用 console.log(this.$refs.typeBox)
时,它返回了这个数组:
这就是为什么要使代码正常工作,它必须是 typeBox[0].focus()
而不是 typeBox.focus()
。
终于解决了没有setTimeout
的问题,感谢window.requestAnimationFrame
(不知道为什么):
startTimer () {
window.requestAnimationFrame(() => this.$refs.typeBox.focus())
}
它甚至适用于自定义组件聚焦。
我昨天才开始用 vue.js
编码,我不知道如何在文本框上 "focus" 不使用 "traditional" JS 方式,即 document.getElementById('myTextBox').focus()
.
最初,我的文本框是隐藏的。我有一个 "Start" 按钮,当用户点击它时,会显示文本框,我想在那里设置 focus
,可以这么说。我已经尝试使用 ref
,但无济于事(请参阅下面的代码)。
HTML:
<input id="typeBox" ref="typeBox" placeholder="Type here..." />
Javascript
export default {
name: 'game',
methods: {
startTimer () {
setTimeout(function () { /* .focus() won't work without this */
/* ugly and not recommended */
// document.getElementById('typeBox').focus()
/* Throws the error: Cannot read property 'typeBox' of undefined */
this.$refs.typeBox.focus()
// ... any other options?
// ...
}, 1)
}
} /* END methods */
} /* END export default */
有人知道怎么做吗?请帮忙。
更新:
在 input
上添加 autofocus
可以在页面加载后立即聚焦。但是在我的应用程序中,需要在输入字段上多次 "refocus" 而不重新加载页面,这就是为什么我需要一种方法来调用 .focus()
.
setTimeout
函数中this
的值将被设置为window
对象,因为它是一段时间后执行的回调函数,它已经失去了[的范围=12=] 从调用函数的地方动态设置的关键字。
箭头函数不绑定它自己的 this
值。
startTimer () {
setTimeout(() => {
this.$refs.typeBox.focus()
}, 1)
}
或
startTimer () {
const self = this;
setTimeout(function () {
self.$refs.typeBox.focus()
}, 1)
}
在此分享解决方案,以防有人遇到同样的问题...
在高级程序员的帮助下,我终于弄明白了。我也能够一路消除 setTimeout
,使用它的 vue
版本 nextTick()
.
正确的JS代码:
startTimer () {
this.$nextTick(() => {
// this won't work because `this.$refs.typeBox` returns an array
// this.$refs.typeBox.focus()
//this one works perfectly
this.$refs.typeBox[0].focus()
})
} /* END startTimer */
解释:
当我使用 console.log(this.$refs.typeBox)
时,它返回了这个数组:
这就是为什么要使代码正常工作,它必须是 typeBox[0].focus()
而不是 typeBox.focus()
。
终于解决了没有setTimeout
的问题,感谢window.requestAnimationFrame
(不知道为什么):
startTimer () {
window.requestAnimationFrame(() => this.$refs.typeBox.focus())
}
它甚至适用于自定义组件聚焦。