'Vue.js 3 use autofocus on input with ref inside a method

I worked with Vue2, but I recently try Vue 3.

I have simple problem:

 <input ref="myinput" />
 <button @click="submitData" />

I want to set "focus" on "myinput", inside function "submitData". In Vue 2 it is simple (this.$refs ...), but in Vue 3, they made it complicated. I saw example with "setup", but is no use for me + I think you can only access "value" from element.

Is there any way to execute "focus" on on element inside methods?



Solution 1:[1]

You are still able to do the same thing using Vue 3, but if you work with composition api there's some difference :

Options API :

const {
  createApp
} = Vue;
const App = {

  data() {
    return {

    }
  },
  methods: {
    submitData() {
      this.$refs.myinput.focus()
    }
  },
  mounted() {

  }
}
const app = createApp(App)
app.mount('#app')
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>

<div id="app">
  Vue 3 app
  <input ref="myinput" />
  <button @click="submitData">
  Submit
  </button>
</div>

composition API:

const {
  createApp,
  ref,
  onMounted,

} = Vue;
const App = {

  setup() {
    const myinput = ref(null)

    function submitData() {
      myinput.value.focus()
    }

    return {
      myinput,
      submitData
    }
  }
}
const app = createApp(App)
app.mount('#app')
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>

<div id="app">
  Vue 3 app
  <input ref="myinput" />
  <button @click="submitData">
  Submit
  </button>
</div>

Solution 2:[2]

In case someone comes to this question looking for a way to set the autofocus of a specific element in Vue3, you can achieve it using a Vue Custom Directive

const { createApp, onMounted } = Vue;

const app = createApp({})

// Register a global custom directive called `v-focus`
app.directive('focus', {
  // When the bound element is mounted into the DOM...
  mounted(el) {
    // Focus the element
    el.focus()
  }
})

app.mount('#app')
<script src="https://unpkg.com/vue@next"></script>

<div id="app">
    <input />
    <input v-focus />
    <input />
</div>

Solution 3:[3]

Easiest answer I found is missing here

<input type="text" autofocus />

Solution 4:[4]

In some cases when the input is hidden under a v-show or v-if it is necessary to do a nextTick for the focus to work.

<span
    v-show="!editMode"
    @click="handleEditionMode"
>
    {{ content }}
</span>
<input
    v-show="editMode"
    ref="input"
    v-model="content"
    aria-describedby="item-content"
    name="content"
    type="text"
    tabindex="0"
    @focusout="editMode = false"
    @keydown.enter="editMode = false"
/>
const input = ref(null),
    editMode = ref(false);

const handleEditionMode = () => {
    editMode.value = true;
    nextTick(() => {
        input.value.focus();
    });
};

Solution 5:[5]

I was trying to select a specific input upon loading the form component.

The above examples were not useful, so I figured it out myself.

This is far simpler, IMHO. Add 1 ref tag and 1 line of code in the mounted hook.

Place a ref tag on the item you'd like to focus. Here I named it "formStart" but you can name yours whatever you like.

<form @submit.prevent="createNewRoute">
  <label for="code">Code</label>
  <input v-model="code" id="code" type="text" ref="formStart" /> <!-- REF TAG HERE -->
  <label for="type">Type</label>
  <input v-model="type" id="type" type="text" />
  /* Other inputs hidden for simplicity */
  <button type="submit">Add Route</button>
</form>

Reference that ref tag in the mounted hook and focus() it.

<script>
export default {
  /* Other options hidden for simplicity */
  mounted() {
    this.$refs.formStart.focus(); // FOCUS ELEMENT HERE
  },
};
</script>

Solution 6:[6]

Another vanilla solution is:

document.getElementById("code")?.focus()

to be called on onMounted

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 webcu
Solution 3 Akif
Solution 4 MrEduar
Solution 5
Solution 6 Uncoke