VueJS 速習チュートリアル

Vue メソッド

Vue メソッド(Methods) は、methods プロパティの下に定義される、Vue インスタンスに属するファンクションです。

Vue メソッドは、イベントハンドリング(v-on)と組み合わせて複雑な処理を行うのに非常に適しています。また、イベントハンドリング以外の用途でも利用することが可能です。

1. Vue の 'methods' プロパティ

このチュートリアルでは、値を保存するための data プロパティをすでに使用しました。
Vue にはもう一つ、Vue インスタンスに属するファンクションを保存するための methods というプロパティがあります。メソッドは、Vue インスタンス内に次のように定義できます。

const app = Vue.createApp({
  data() {
    return {
      text: ''
    }
  },
  methods: {
    writeText() {
      // メソッド内からデータプロパティを参照する場合、接頭辞として 'this.' を記述する必要があります
      this.text = 'Hello World!'
    }
  }
})

<div> 要素をクリックしたときに writeText メソッドを呼び出すには、以下のコードを記述します。

<div v-on:click="writeText"></div>

実際の動作例は以下のようになります。

1.1 使用例:クリックでテキストを変更

<div> 要素に v-on ディレクティブを使用して click イベントをリッスンします。クリックイベントが発生すると writeText メソッドが呼び出され、テキストが変更されます。

<div id="app">
  <p>下のボックスをクリックしてください:</p>
  <div v-on:click="writeText">
    {{ text }}
  </div>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        text: ''
      }
    },
    methods: {
      writeText() {
        this.text = 'Hello World!(こんにちは、世界!)'
      }
    }
  })
  app.mount('#app')
</script>

2. イベントオブジェクトを使用したメソッドの呼び出し

イベントが発生してメソッドが呼び出される際、デフォルトで イベントオブジェクト(Event Object) がメソッドに渡されます。イベントオブジェクトには、ターゲットとなるオブジェクト、イベントのタイプ、あるいは clickmousemove が発生した際のマウス位置など、多くの有用なデータが含まれているため、非常に便利です。

2.1 使用例:マウス座標の取得

<div> 要素で mousemove イベントをリッスンします。イベントが発生すると mousePos メソッドが呼び出され、デフォルトで渡されるイベントオブジェクトからマウスカーソルの位置を取得します。

<div id="app">
  <p>下のボックスの上でマウスを動かしてください:</p>
  <div v-on:mousemove="mousePos" style="width:200px;height:100px;background-color:lightgray;"></div>
  <p>xPos: {{ xPos }}, yPos: {{ yPos }}</p>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        xPos: 0,
        yPos: 0
      }
    },
    methods: {
      mousePos(event) {
        // インスタンス内のデータにアクセスするために 'this.' を使用
        this.xPos = event.offsetX
        this.yPos = event.offsetY
      }
    }
  })
  app.mount('#app')
</script>

上記の例に一行追加するだけで、マウスカーソルの X 方向の位置に基づいて背景色を変化させることもできます。v-bind を使用して style 属性の background-color を動的に変更します。

2.2 使用例:座標に連動した背景色変更

背景色が xPos にバインドされており、HSL の色相(Hue)の値が xPos と等しくなるように設定されています。

<div
  v-on:mousemove="mousePos"
  v-bind:style="{backgroundColor:'hsl('+xPos+',80%,80%)'}">
</div>

2.3 使用例:テキストエリアからのリアルタイム入力

この例では、イベントオブジェクトが <textarea> タグからテキストを運び、ノートに書いているような動作を実現します。

<div id="app">
  <textarea v-on:input="writeText" placeholder="書き始めてください..."></textarea>
  <span>{{ text }}</span>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        text: ''
      }
    },
    methods: {
      writeText(event) {
        // event.target.value から入力値を取得
        this.text = event.target.value
      }
    }
  })
  app.mount('#app')
</script>

3. 引数の受け渡し

イベントが発生した際に、メソッドに 引数(Arguments) を渡したい場合があります。

例えば、あなたが森林警備員で、ヘラジカ(Moose)の目撃数を記録しているとしましょう。1頭や2頭のこともあれば、1日に10頭以上見ることもあります。そこで「+1」「+5」といったカウントボタンと、数えすぎたときのための「-1」ボタンを追加します。

この場合、3つのボタンすべてに同じメソッドを使用し、ボタンごとに異なる数値を引数として渡すことができます。

3.1 メソッド呼び出しの構文

<button v-on:click="addMoose(5)">+5</button>

3.2 メソッドの定義

methods: {
  addMoose(number) {
    this.count = this.count + number
  }
}

3.3 実装例:ヘラジカ・カウンター

引数を利用して、一つのメソッドで異なる加算・減算処理を行います。

<div id="app">
  <img src="img_moose.jpg" style="width:100px;">
  <p>{{ "ヘラジカの目撃数: " + count }}</p>
  <button v-on:click="addMoose(+1)">+1</button>
  <button v-on:click="addMoose(+5)">+5</button>
  <button v-on:click="addMoose(-1)">-1</button>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        count: 0
      }
    },
    methods: {
      addMoose(number) {
        this.count += number
      }
    }
  })
  app.mount('#app')
</script>

4. 引数とイベントオブジェクトの両方を渡す

イベントオブジェクトと他の引数の両方を渡したい場合は、メソッド呼び出し時に予約済みの名称である $event を使用します。

4.1 構文例

<button v-on:click="addAnimal($event, 5)">+5</button>

4.2 メソッド側の受け取り

methods: {
  addAnimal(e, number) {
    if(e.target.parentElement.id === "tigers"){
      this.tigers = this.tigers + number
    }
  }
}

4.3 使用例:イベント情報とメッセージの同時取得

この例では、メソッドがイベントオブジェクトと任意のテキストの両方を受け取ります。

<div id="app">
  <img
    src="img_tiger.jpg"
    id="tiger"
    style="width:100px;"
    v-on:click="myMethod($event,'こんにちは')">
  <p>"{{ msgAndId }}"</p>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        msgAndId: ''
      }
    },
    methods: {
      myMethod(e, msg) {
        this.msgAndId = msg + ', '
        // クリックされた要素の ID を取得
        this.msgAndId += e.target.id
      }
    }
  })
  app.mount('#app')
</script>

5. 応用例:単一メソッドによる複数カウンターの制御

この例では、一つのメソッドだけを使用して、3種類の動物をそれぞれ異なる数値でカウントできることを示します。これは、イベントオブジェクトと増減する数値の両方を渡すことで実現しています。

予約語 $event を使用してイベントオブジェクトを渡し、どの動物がカウント対象であるかをメソッド内で判別します。

<div id="app">
  <div id="tigers">
    <p>トラ (Tigers)</p>
    <button v-on:click="addAnimal($event,1)">+1</button>
    <button v-on:click="addAnimal($event,5)">+5</button>
    <button v-on:click="addAnimal($event,-1)">-1</button>
  </div>
  <div id="moose">
    <p>ヘラジカ (Moose)</p>
    <button v-on:click="addAnimal($event,1)">+1</button>
    <button v-on:click="addAnimal($event,5)">+5</button>
    <button v-on:click="addAnimal($event,-1)">-1</button>
  </div>
  <div id="kangaroos">
    <p>カンガルー (Kangaroos)</p>
    <button v-on:click="addAnimal($event,1)">+1</button>
    <button v-on:click="addAnimal($event,5)">+5</button>
    <button v-on:click="addAnimal($event,-1)">-1</button>
  </div>
  <hr>
  <ul>
    <li>トラ: {{ tigers }} </li>
    <li>ヘラジカ: {{ moose }} </li>
    <li>カンガルー: {{ kangaroos }} </li>
  </ul>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  const app = Vue.createApp({
    data() {
      return {
        tigers: 0,
        moose: 0,
        kangaroos: 0
      }
    },
    methods: {
      addAnimal(e, number) {
        // 親要素の ID に基づいて、どのデータを更新するか分岐させる
        const parentId = e.target.parentElement.id;
        if(parentId === "tigers") {
          this.tigers += number
        }
        else if(parentId === "moose") {
          this.moose += number
        }
        else {
          this.kangaroos += number
        }
      }
    }
  })
  app.mount('#app')
</script>