Vue: How to call .focus() on button click

Finally solved the problem without setTimeout, thanks to window.requestAnimationFrame (I don't know why):

startTimer () {
    window.requestAnimationFrame(() => this.$refs.typeBox.focus())
}

It works even for custom component focusing.


Sharing the solution here just in case someone encounters the same problem...

I finally figured this out with the help of a senior programmer. I was also able to eliminate setTimeout along the way, using its vue version nextTick().

The correct JS code:

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 */

Explanation:

When I used console.log(this.$refs.typeBox), it returned this array:

enter image description here

That's why for the code to work, it had to be typeBox[0].focus() instead of typeBox.focus().


The value of this in the setTimeout function will be set to window object since it is callback function executing after a period of time and it had lost the scope of this keyword which is dynamically set from where the function is being called.

Arrow functions doesn't bind it's own value of this.

startTimer () {
  setTimeout(() => {
    this.$refs.typeBox.focus()
  }, 1)
}

OR

startTimer () {
  const self = this;
  setTimeout(function () {
    self.$refs.typeBox.focus()
  }, 1)
}