Background question

  • How to get focus for input in vue3?
  • How does vue3 setup syntactic sugar get the dom element?

The vue2 approach

In vue2, after setting the ref property on a component, you can access the corresponding DOM element via this.$refs.ref.

1
<input type="text" ref="inputRef" />

In JavaScript you can access.

1
this.$refs.usernameInput

If you need to focus on the input box.

1
this.$refs.usernameInput.focus()

vue3

There are no $refs in vue3, and there is no this, so you can use the ref() API to implement.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<template>
  <input type="text" ref="inputRef" />
  <span @click="handleFocus">focus</span>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const inputRef = ref();

console.log(inputRef.value); // undefined!页面元素尚未渲染

onMounted(() => {
  console.log(inputRef.value); // 可以拿到 input 元素!
});

const handleFocus = () => {
  inputRef.value.focus(); // 成功聚焦
};
</script>

What if there are multiple input elements?

If each input box corresponds to a focus button, then we can wrap them into a Vue component so that there is only one input in each component!

Alternatively, you can use an array to achieve this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<template>
  <div v-for="(item, index) in data">
    <input type="text" :ref="inputRef" />
    <span @click="handleFocus(index)">focus</span>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
const data = [1, 2, 3, 4, 5];

const refArr = ref([]);
const inputRef = (el) => {
  refArr.value.push(el);
};

const handleFocus = (index) => {
  refArr.value[index].focus();
};
</script>