Vue.jsのTodoアプリのサンプルを参考にTodoアプリを作成した際に知った、ダブルクリック後に出現するフォームにオートフォーカスする方法についてのメモ。
実際にelectron-vueで作成したTodoアプリは https://github.com/x-color/todo-app に置いてある。
どうなるか
before
ダブルクリック後にフォームが出現しているのだが、オートフォーカスしていない。
after
ダブルクリック後にフォームが出現し、オートフォーカスしている。
何をしているのか
Todoを表示する部分。ダブルクリック時にeditTodo()
を実行する。
<label @dblclick="editTodo(todo)">{{ todo.title }}</label>
入力フォーム部分。v-if
で描画するかを制御している。
<input v-if="todo.isEditing" id="edit-todo" v-model="todo.title" type="text">
Todoがダブルクリックされた場合に実行される関数。入力フォーム部分の描画条件をtrue
にして、自動で入力フォームにフォーカスしている。
editTodo(todo) {
todo.isEditing = true;
this.$nextTick(() => document.getElementById('edit-todo').focus());
}
簡単な解説
v-if
で描画を制御している場合、条件が真になった直後に、
document.getElementById('id').focus();
このコードを実行してもフォーカスしない。これは、条件が真になった直後にDOMが更新されているとは限らないため。
なので、DOMの更新を待った後に実行するために、以下のようにnextTick()
を用いて呼び出す必要がある。
nextTick(() => document.getElementById('id').focus());
備考
バージョンや実行環境によって、nextTick()
の挙動が変わるので注意。
Vue.nextTick(() => document.getElementById('id').focus());
// Promiseがサポートされている実行環境かつ、Vue.js 2.1.0以上
Vue.nextTick().then(() => document.getElementById('id').focus());
詳しくは https://jp.vuejs.org/v2/api/index.html#Vue-nextTick を参照