はじめに
この記事は、Vue3系でDOM構築後に出現したinput要素に対してfocusを当てることでnextTick() で同期的にDOM要素を操作する方法を説明します。
使用技術
- Vue3
- CompositionAPI
- script setup
やりたいこと
DOM構築後に出現したinput要素に対してfocusを当てる
結論
await nextTick();
でコンポーネントのデータ変更がDOMに到達するのを待つ
App.vue
<template>
<button @click="handleClick">button</button>
<input v-if="show" ref="input" />
</template>
<script setup>
import { ref, onMounted, nextTick } from "vue";
const input = ref();
const show = ref(false);
const handleClick = async () => {
show.value = !show.value;
await nextTick();
input.value?.focus();
};
</script>
解説
上記コードにコメントベースで解説します。
App.vue
<template>
<button @click="handleClick">button</button>
<!-- DOMにアクセスするため、refを使用してテンプレート参照を行う -->
<input v-if="show" ref="input" />
</template>
<script setup>
import { ref, onMounted, nextTick } from "vue";
// inputタグで ref="input" としたため、 変数名を合わせ、refの引数を空にすることでDOMの内容を変数に受け取る
const input = ref();
// inputタグの表示非表示を管理する変数
const show = ref(false);
/**
* buttonクリックイベント
* inputタグの表示制御、focus制御を行う
*/
const handleClick = async () => {
// inputタグの表示制御
show.value = !show.value;
// nextTickが引数なしで呼ばれた場合、コンポーネントのデータ変更がDOMに到達した時に解決されるPromiseを返します。
// つまり、inputタグが実際に出現するまで処理を待ってくれます。
await nextTick();
// フォーカス
input.value?.focus();
};
</script>