基礎からメモ: Vue.js CH2-p59 データの更新

v-onディレクティブを使って、ボタンクリックでデータを更新するサンプル。

[main05.js]

var app = new Vue({
  el: '#app',
  data: {
    count: 0
  },
  methods: {
    increment: function(event) {
      let that = this;
      that.count += 1;
  }
})

次のHTMLで、v-on:click="increment"という形で、クリックするとVueインスタンスmethods.incrementが呼び出されるて、データのcountが+1される。

[index05.html]

  <div id="app">
  <!-- countプロパティを表示する  -->
      <p>{{ count }}回クリックしたよ!</p>
      <!-- このボタンをクリックするとincrementメソッドが呼び出される -->
      <button v-on:click="increment">カウントを増やす</button>
      <pre>{{ $data }}</pre>
  </div>

Vueインスタンス側で、let that = this; that.count += 1としている。インスタンスのメソッド内でのthisインスタンスそのものを指すので、this.countapp.countを表している。ここではいったんthatに代入して使っているがメソッド内でやってもこの程度の内容では意味は無い。

むしろインスタンスapp変数に代入しているので、メソッド内でもこれを使った方がわかりやすい。

  methods: {
    increment: function(event){
      app.count += 1;
    }
  }

Vueインスタンス内でのthis

setTimeoutの中でのthisWindowオブジェクトを指すので、これは機能しない。

    setTimeout(function() { this.count++ }, 100);

そこでthisを変数に代入しておくと機能する。メソッド内でthisを別の変数に代入しておくのは、こういう場合に活きてくる。

    let vm = this;
    setTimeout(function() { vm.count++ }, 100);

setTimeoutの中だけの問題ならbindで紐付ける方法もある。

    setTimeout(function() { this.count++ }.bind(this), 100);

アロー関数は、Vueインスタンスを指すthisにアクセスできる。

    setTimeout(()=> { this.count++ }, 100);

インスタンス内の別のメソッドを介すると機能する。

methods: {
    increment: function(event){
      setTimeout(this.count_p, 100);
    },
    count_p: function() {
      this.count++;
    }
  }

同じコードでこのcount_pメソッドをアロー関数にしてしまうと機能しない。アロー関数のメソッドのスコープはインスタンスの外側になる。

    count_p: () => {
      this.count++;
    }

逆に短縮記法なら問題ない。

    count_p() {
      this.count++;
    }
  • v-on:イベント名="メソッド名"という形で、HTML側からVueインスタンスのメソッドを呼び出せる。
  • メソッド内でthisを使う場合は、正しくインスタンス自体を指す書き方を選ぶ。