ブログ

読んで思い出す。忘れるために書く

キーボード操作で <input/> を増減させる

ゴール

コンポーネント、「InputEditor」を作成する

f:id:innocent-zero:20180401085235g:plain

機能は次の通り実装する:

  • ボタンクリックで要素を増やす
  • <h1/> で、増減するカウント数を表示する
  • キーボード操作で <input/>素数の増減ができる
    • [Ctrl] + [Enter] で増やす
    • [Ctrl] + [BackSpace] で減らす
  • 要素の数が変わったときに、最後の要素に入力フォーカスを当てる

前提

  • Vue.js の ガイド などドキュメントにある程度 目を通した
  • vue-cli を使っている
  • vue-cliREADME.md を読んだのでプロジェクトの初期化方法がわかる
  • iView を使っている(なくてもいい)

説明しないこと

コンポーネントの作成

ファイル src/components/InputEditor.vue を作って書いていく

<tamplate/> の記述

カウント数に合わせて <input/> 要素の数が変化する単純なもの

<template>
  <div>
    <h1>{{ counter }}</h1>
    <Button type="primary" @click.left="countUp">Button</Button>
    <div v-for="i in counter" :key="i">
      <input @keyup.ctrl.backspace="countDown" @keyup.ctrl.enter="countUp" type="text" ref="input">
    </div>
  </div>
</template>

日本語入力での確定 [Enter] と操作が被るので、[Ctrl] を @keyup イベントでのキーの組み合わせに使う

素数が変わった後の入力フォーカス設定をしたいので、スクリプト側から参照できるように ref 属性値を設定

デフォルトで用意されていない [backspace] については後述

<script/> の記述

<script>
export default {
  name: 'InputEditor',
  data () {
    return {
      counter: 1
    }
  },
  methods: {
    focusToLast: function () {
      this.$refs.input.slice(0).pop().focus()
    },
    countDown: function () {
      this.counter--
      this.$nextTick(this.focusToLast)
    },
    countUp: function () {
      this.counter++
      this.$nextTick(this.focusToLast)
    }
  }
}
</script>

$nextTick

$nextTick で入力フォーカスの設定をしているのは、入力要素数の実際の増減が走るのが カウントの増減処理のあとになるため

  • ボタンクリック or キーボード操作...イベント発生 で countUp メソッド呼び出し
  • counter の値が増える
  • 入力要素を管理している <div/> に変更が伝わり v-for が再処理され、差分が表示結果として更新される

という流れなのだと思う

$refs

$refs から入力要素の一覧を取得して、最後の要素が欲しいので .pop() を 使う... 前に .slice(0) でコピーしたものを使う(非破壊操作)

キーコード

デフォルト キーコード一覧

デフォルトで対応しているキーコードが意外と少ない

Here’s the full list of key modifier aliases:

  • .enter

  • .tab

  • .delete (captures both “Delete” and “Backspace” keys)

  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

https://vuejs.org/v2/guide/events.html#Key-Modifiers

この一覧にない [BackSpace] を使いたいので (.delete ではなく)、これを拡張する

キーコード 一覧の拡張

検索してきて見つけた、 codingcarpenter 氏の Gist ファイル を用いる

たとえば次のように src/keycodes.js ファイルとして保存する

export default {
  backspace: 8,
  tab: 9,
  enter: 13,
  shift: 16,
  ctrl: 17,
// ....
}

src/main.js でファイルのインポートとキーコード一覧の設定変更をする

import KeyCodes from '@/keycodes'

Vue.config.keyCodes = KeyCodes

Links