CH3 イベントとフォーム入力の受け取り

S13 イベントハンドリング

96~104ページ

メソッドイベントハンドラ

96ページ

<button v-on:click="handleClick">クリック</button>
new Vue({
  el: '#app',
  methods: {
    handleClick: function () {
      alert('クリックしたよ')
    }
  }
})

フォーム入力の取得

98ページ

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

イベント修飾子

99ページ

<div v-on:click.right="handler">example</div>
<!-- 右ボタンを押した時のコンテキストメニューを表示させない -->
<div v-on:click.right.prevent="handler">example</div>
new Vue({
  el: '#app',
  methods: {
    handler: function (comment) {
      console.log(comment)
    }
  }
})

.stop

<div v-on:click="handler('div1')">
  div1
  <a href="#top" v-on:click.stop="handler('div2')">div2</a>
</div>

.prevent

<div v-on:click="handler('div1')">
  div1
  <a href="#top" v-on:click.prevent="handler('div2')">div2</a>
</div>

.capture

<div v-on:click.capture="handler('div1')">
  div1
  <div v-on:click="handler('div2')">
    div2
    <div v-on:click="handler('div3')">div3</div>
  </div>
</div>

.native

<!-- コンポーネントをクリックするとハンドラが呼び出される -->
<my-component v-on:click.native="handler"></my-component>
<!-- コンポーネントをクリックしてもハンドラは呼び出されない -->
<my-component v-on:click="handler"></my-component>

S14 フォーム入力バインディング

105~113ページ

複数行テキスト

108ページ

<textarea v-model="message"></textarea>
<pre>{{ message }}</pre>
new Vue({
  el: '#app',
  data: {
    message: 'Hello!'
  }
})
DEMO
Hello!
guide-ch3-demo06

チェックボックス

108ページ

単一要素

<label>
  <input type="checkbox" v-model="val"> {{ val }}
</label>
new Vue({
  el: '#app',
  data: {
    val: true
  }
})
DEMO
guide-ch3-demo07

複数要素

<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>
new Vue({
  el: '#app',
  data: {
    val: []
  }
})
DEMO

[]

guide-ch3-demo08

ラジオボタン

110ページ

<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>
new Vue({
  el: '#app',
  data: {
    val: ''
  }
})
DEMO

guide-ch3-demo09

セレクトボックス

110ページ

単一要素

<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>
new Vue({
  el: '#app',
  data: {
    val: ''
  }
})
DEMO

guide-ch3-demo10

複数要素

<select v-model="val" multiple>
  <option value="a">A</option>
  <option value="b">B</option>
  <option value="c">C</option>
</select>
<p>{{ val }}</p>
new Vue({
  el: '#app',
  data: {
    val: []
  }
})
DEMO

[]

guide-ch3-demo11

画像ファイル

111ページ

<input type="file" v-on:change="handleChange">
<div v-if="preview"><img v-bind:src="preview"></div>
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)
      }
    }
  }
})
DEMO
guide-ch3-demo12

※ ここでの画像の選択は、ブラウザでプレビューするためのみに使用され、サーバーにアップロードする処理はしていません。

S15 マウント要素外のイベントと操作

114~116ページ

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

114ページ

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)
      }
    }
  }
})

スムーススクロールの実装

115ページ

<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>
var scroll = new SmoothScroll()
new Vue({
  el: '#app',
  methods: {
    scrollTop: function () {
      scroll.animateScroll(0)
    }
  }
})

COLUMN Vue.js以外からのイベントの受け取り

117ページ

<div id="app">
  <input id="message" v-on:input="handleInput">
  <button data-update="jQuery!">jQueryからの更新</button>
</div>
$(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)
    }
  }
})