Vue.jsにおけるmethodsの使い方

2025-07-29

はじめに

methods(メソッド)とは、特定の目的を達成するための手順や方法、方式、手法のことです。Vue.jsのmethodsは、コンポーネント内で使用する関数を定義するための重要なオプションです。このガイドでは、methodsの基本的な使い方から応用パターンまで、詳細に解説していきます。

methodsの基本概念

methodsはVueコンポーネントで使用する関数を定義するオブジェクトです。テンプレート内でのイベントハンドリングや、コンポーネントロジックの整理に使用されます。

export default {
  methods: {
    greet() {
      console.log('Hello, Vue.js!');
    }
  }
}

methodsの登録方法

methodsをコンポーネントに登録するには、コンポーネントオプションのmethodsプロパティを使用します。

export default {
  data() {
    return {
      message: 'Hello Vue!'
    }
  },
  methods: {
    showMessage() {
      alert(this.message);
    },
    changeMessage(newMessage) {
      this.message = newMessage;
    }
  }
}

テンプレートからのmethods呼び出し

登録したmethodsは、テンプレート内で直接呼び出すことができます。

<template>
  <div>
    <button @click="showMessage">メッセージ表示</button>
    <button @click="changeMessage('New Message')">メッセージ変更</button>
  </div>
</template>

methodsとdataの連携

methods内ではthisを通じてdataプロパティにアクセスできます。

export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    },
    reset() {
      this.count = 0;
    }
  }
}

イベントハンドリングでの使用

methodsは主にイベントハンドラとして使用されます。

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">増やす</button>
    <button @click="decrement">減らす</button>
    <button @click="reset">リセット</button>
  </div>
</template>

引数の受け渡し

methodsに引数を渡すことも可能です。

export default {
  methods: {
    greet(name) {
      alert(`Hello, ${name}!`);
    }
  }
}
<template>
  <button @click="greet('Alice')">Aliceに挨拶</button>
  <button @click="greet('Bob')">Bobに挨拶</button>
</template>

イベントオブジェクトの利用

DOMイベントオブジェクトにアクセスするには、$eventを使用します。

export default {
  methods: {
    handleClick(event) {
      console.log('クリック位置:', event.clientX, event.clientY);
    }
  }
}
<template>
  <button @click="handleClick($event)">クリック</button>
</template>

methodsとcomputedの違い

methodscomputedは似ていますが、重要な違いがあります。

export default {
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe'
    }
  },
  computed: {
    fullName() {
      // 依存するデータが変更された時のみ再計算
      return `${this.firstName} ${this.lastName}`;
    }
  },
  methods: {
    getFullName() {
      // 呼び出されるたびに常に再計算
      return `${this.firstName} ${this.lastName}`;
    }
  }
}

アロー関数の注意点

methodsでアロー関数を使用するとthisが意図しない値を指すことがあるので注意が必要です。

export default {
  data() {
    return {
      message: 'Hello'
    }
  },
  methods: {
    // これは動作する
    regularFunction() {
      console.log(this.message);
    },
    // これは動作しない(thisがundefined)
    arrowFunction: () => {
      console.log(this.message); // Error
    }
  }
}

非同期処理の扱い

methods内で非同期処理を行う例です。

export default {
  methods: {
    async fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
      } catch (error) {
        console.error('Error:', error);
      }
    }
  }
}

他のmethodsの呼び出し

あるmethodsから別のmethodsを呼び出すことも可能です。

export default {
  methods: {
    validateInput(input) {
      return input.length > 0;
    },
    submitForm() {
      if (this.validateInput(this.username)) {
        // フォーム送信処理
      } else {
        alert('入力が無効です');
      }
    }
  }
}

ライフサイクルフックとの組み合わせ

methodsをライフサイクルフックで呼び出す例です。

export default {
  mounted() {
    this.loadData();
  },
  methods: {
    loadData() {
      // 初期データ読み込み
    }
  }
}

実践的な例: フォーム処理

methodsを使用したフォーム処理の実例です。

export default {
  data() {
    return {
      form: {
        name: '',
        email: '',
        message: ''
      },
      isSubmitting: false
    }
  },
  methods: {
    validateForm() {
      return this.form.name && this.form.email.includes('@');
    },
    async submitForm() {
      if (!this.validateForm()) {
        alert('入力内容に誤りがあります');
        return;
      }

      this.isSubmitting = true;

      try {
        await fetch('/api/contact', {
          method: 'POST',
          body: JSON.stringify(this.form)
        });
        alert('送信成功');
        this.resetForm();
      } catch (error) {
        console.error(error);
        alert('送信失敗');
      } finally {
        this.isSubmitting = false;
      }
    },
    resetForm() {
      this.form = {
        name: '',
        email: '',
        message: ''
      };
    }
  }
}

ミックスインとの組み合わせ

methodsをミックスインで共有する方法です。

// formMixin.js
export default {
  methods: {
    validateEmail(email) {
      const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      return re.test(email);
    }
  }
}

// コンポーネントで使用
import formMixin from './formMixin';

export default {
  mixins: [formMixin],
  methods: {
    submit() {
      if (this.validateEmail(this.email)) {
        // 有効なメールアドレス
      }
    }
  }
}

パフォーマンスに関する考慮事項

methodsのパフォーマンス最適化についてのポイントです。

export default {
  methods: {
    // 重い処理をメモ化する例
    heavyComputation(input) {
      // 重い計算処理
      return result;
    },

    // 代わりにcomputedプロパティを使用する方が良い場合
    computedResult() {
      // このような場合はcomputedプロパティの使用を検討
    }
  }
}

テストの書き方

methodsの単体テストの例です。

import { shallowMount } from '@vue/test-utils';
import MyComponent from './MyComponent.vue';

describe('MyComponent', () => {
  it('increments count when increment method is called', () => {
    const wrapper = shallowMount(MyComponent);
    wrapper.vm.increment();
    expect(wrapper.vm.count).toBe(1);
  });

  it('resets count to 0 when reset method is called', () => {
    const wrapper = shallowMount(MyComponent, {
      data() {
        return { count: 5 };
      }
    });
    wrapper.vm.reset();
    expect(wrapper.vm.count).toBe(0);
  });
});

よくある間違いとベストプラクティス

methods使用時の注意点と推奨される方法です。

export default {
  methods: {
    // 悪い例: データの直接変更とロジックが混在
    processDataBad() {
      this.data = fetchData();
      this.filterData();
      this.sortData();
      this.renderData();
    },

    // 良い例: 単一責任の原則に従う
    async fetchData() {
      this.data = await api.getData();
    },
    filterData() {
      // フィルタリング処理
    },
    sortData() {
      // ソート処理
    },
    async processDataGood() {
      await this.fetchData();
      this.filterData();
      this.sortData();
    }
  }
}

まとめ

Vue.jsのmethodsはコンポーネントの動作を定義する核となる機能です。このガイドで学んだことを活かして、以下のポイントを意識して開発を行いましょう。

  1. 関連する機能はまとめてmethodsに定義する
  2. 単一責任の原則に従い、1つのメソッドは1つの処理のみ行う
  3. データ操作はmethods内で行い、テンプレート内で複雑なロジックを書かない
  4. 非同期処理にはasync/awaitを活用する
  5. 他のmethodsやcomputedプロパティと組み合わせて使用する

methodsを適切に使用することで、より整理されたメンテナンス性の高いVue.jsアプリケーションを構築できます。