LoginSignup
0
2

More than 3 years have passed since last update.

【Vue.js - 3】イベントとフォーム入力の受け取り

Last updated at Posted at 2019-06-07

1. イベントハンドラ

html
<!-- メソッドイベントハンドラ -->
<button v-on:click="handleClick">クリック</button>
<!-- 省略記述 -->
<button @click="handleClick">クリック</button>

<!-- インラインメソッドハンドラ -->
<button v-on:click="count++"></button>

<!-- 引数(元のイベントオブジェクトとスコープ内のitem) -->
<button v-on:click="handleClick($event, item)">クリック</button>

フォーム入力の取得
(v-modelを使用するとシンプルになるが、v-onを使用することで入力内容を確認してからデータに代入するといったフック処理ができる)

html
<input v-bind:value="message" v-on:change="handleInput">
Vue.js
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js',
  },
  methods: {
    handleInput: function (event) {
      //代入前に何か処理を行う…
      this.message = event.target.value
    }
  }
})

イベント修飾子

修飾子 作用
.stop event.stopPropagation()を呼ぶ
.prevebt event.preventDefault()を呼ぶ
.capture キャプチャモードでDOMイベントをハンドルする
.self イベントがこの要素から発火した時のみハンドラを呼び出す
.native コンポーネントのルート要素上のネイティブイベントをハンドルする
.once 最大1回ハンドラを呼び出す
.passive {passive:ture}でDOMイベントをハンドルする

クリックイベントの修飾子

修飾子 作用
.left マウスの左ボタンが押された時のみハンドラを呼び出す
.right マウスの右ボタン…
.middle マウスの中央ボタン…

キー修飾子

html
<input v-on:keydown.13="handler">
<!-- よく使用されるキーコードはエイリアスとして登録されている -->
<input v-on:keydown.enter="handler">

使用可能なキーコードのエイリアス

修飾子 作用
.enter エンターキーが押された時
.tab Tabキーが押された時
.delete Deleteキーが押された時
.esc ESCキーが押された時
.space スペースキーが押された時
.up 矢印の上キーが押された時
.down 矢印の下キーが押された時
.left 矢印の左キーが押された時
.right 矢印の右キーが押された時

複数つけた場合、ORを意味する

html
<input v-on:keydown.up.down.left.right="handler">

システム修飾子

修飾子 作用
.ctrl Ctrlキーが押されている場合
.alt Altキーが押されている場合
.shift Shiftキーが押されている場合
.meta Metaキーが押されている場合

2. フォーム入力バインディング(v-model)

双方向データバインディング(フォームの入力値および選択値をデータと同期させる)

インプット

html
<input v-model="message">
<p>{{ message }}</p>
Vue.js
new Vue({
  el: '#app',
  data: {
    message: 'Hello!'
  }
})

テキストエリア

html
<textarea v-model="message"></textarea>
<pre>{{ message }}</pre>
Vue.js
new Vue({
  el: '#app',
  data: {
    message: 'Hello!'
  }
})

チェックボックス(単一要素)

html
<label>
  <input type="checkbox" v-model="val"> {{ val }}
</label>
Vue.js
new Vue({
  el: '#app',
  data: {
    val: true//値の型はBoolean
  }
})

チェックボックス(複数要素)

html
<label><input type="checkbox" v-model="val" value="A"> A</label>
<label><input type="checkbox" v-model="val" value="B"> B</label>
<label><input type="checkbox" v-model="val" value="C"> C</label>
<p>{{ val }}</p>
Vue.js
new Vue({
  el: '#app',
  data: {
    val: []//値の型は配列 チェックされている値が格納される
  }
})

ラジオボタン

html
<label><input type="radio" value="a" v-model="val"> A</label>
<label><input type="radio" value="b" v-model="val"> B</label>
<label><input type="radio" value="c" v-model="val"> C</label>
<p>{{ val }}</p>
Vue.js
new Vue({
  el: '#app',
  data: {
    val: ''//値の型は文字列
  }
})

セレクトボックス(単一要素)

html
<select v-model="val">
  <option disabled="disabled">選択してください</option>
  <option value="a">A</option>
  <option value="b">B</option>
  <option value="c">C</option>
</select>
<p>{{ val }}</p>
Vue.js
new Vue({
  el: '#app',
  data: {
    val: ''//値の型は文字列
  }
})

セレクトボックス(複数要素)

html
<select v-model="val" multiple>
  <option value="a">A</option>
  <option value="b">B</option>
  <option value="c">C</option>
</select>
<p>{{ val }}</p>
Vue.js
new Vue({
  el: '#app',
  data: {
    val: []//値の型は配列
  }
})

画像ファイル

html
<input type="file" v-on:change="handleChange">
<div v-if="preview"><img v-bind:src="preview"></div>
Vue.js
new Vue({
  el: '#app',
  data: {
    preview: ''
  },
  methods: {
    handleChange: function (event) {
      var file = event.target.files[0]
      if (file && file.type.match(/^image\/(png|jpeg)$/)) {
        this.preview = window.URL.createObjectURL(file)
      }
    }
  }
})

range

html
<input type="range" v-model.number="val"> {{ val }}
Vue.js
new Vue({
  el: '#app',
  data: {
    val: 50
  }
})

v-modelの修飾子

修飾子 作用
.lazy inputの代わりにchangeイベントをハンドルする
.number 値を数値に変換する
.trim 値の余分なスペースを削除する

3. マウント要素外(window,body)のイベントと操作

スクロールイベントの取得

Vue.js
new Vue({
  el: '#app',
  data: {
    scrollY: 0,
    timer: null
  },
  created: function () {
    //ハンドラを登録
    window.addEventListener('scroll', this.handleScroll)
  },
  beforeDestroy: function () {
    //ハンドラを解除(コンポーネントやSPAの場合忘れずに!)
    window.removeEventListener('scroll', this.handleScroll)
  },
  methods: {
    //違和感のない程度に200ms間隔でscrollデータを更新する例
    handleScroll: function () {
      if (this.timer === null) {
        this.timer = setTimeout(function () {
          this.scrollY = window.scrollY
          clearTimeout(this.timer)
          this.timer = null
        }.bind(this), 200)
      }
    }
  }
})

ライブラリで実装

html
<script src="https:cdn.jsdelivr.net/npm/smooth-scroll@12.1.5"></script>
<div id="app">
  <div class="content">...</div>
  <div v-on:click="scrollTop">
    ページ上部へ移動
  </div>
</div>
Vue.js
var scroll = new SmoothScroll()
new Vue({
  el: '#app',
  methods: {
    scrollTop: function () {
      scroll.animateScroll(0)
    }
  }
})

Vue.js以外からのイベントの受け取り(dispatchEventを使用してイベントを検知)

html
<div id="app">
  <input id="message" v-on:input="handleInput">
  <button data-update="jQuery!">jQueryからの更新</button>
</div>
Vue.js
$(document).on('click', '[data-update]', function () {
  $('#message').val($(this).attr('data-update'))
  //入力値を更新したらイベントを発生させる
  $('#message')[0].dispatchEvent(new Event('input'))
})
new Vue({
  el: '#app',
  methods: {
    handleInput: function (event) {
      console.log(event.target.value)
    }
  }
})
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2