Vue.js

Vue.js methods are a mechanism for defining functions within a component, allowing you to succinctly organize logic in response to user interactions and events.

methods

Vue.js を使った開発では、「methods」が頻繁に登場します。methods はコンポーネントに定義されたメソッド(関数)の集合であり、ユーザー操作やイベントなどを契機として呼び出されるロジックをまとめる場所として重宝されます。

methodsとは何か?

Vue.js(オプションAPI)においては、コンポーネント内で動的に処理を行いたい時に使用するプロパティが methods です。具体的には、

JavaScript

export default {
	// ...
	methods: {
		methodA() {
			// 処理内容
		},
		methodB(param) {
			// パラメータを受け取り、何らかの処理を行う
		}
	}
}

のようにオブジェクトとして定義し、その中に自由にメソッドを定義していきます。テンプレート(HTML)でのイベントハンドリングや、コンポーネント内の任意の場所から呼び出せるため、非常に便利です。

methods が果たす役割

イベントハンドリング
例えば、ボタンをクリックしたときの処理をまとめる
データ操作
テンプレートでバインドしているデータを動的に変更
外部APIコール
非同期通信で取得したデータを Vue インスタンスの datastate に反映
コンポーネント外部との通信
親コンポーネントから呼び出されたり、Vuex やライブラリとの連携など

methods と computed/watch との違い

Vue.js には、コンポーネント内の状態変化を扱うために、主に以下の 3 つの仕組みが用意されています。

computed
値をキャッシュする。依存しているデータが変わらない限り再計算されないため、高パフォーマンスな算出プロパティを作るときに向いている。
watch
対象のデータが変化したタイミングで処理を実行する。非同期処理のトリガーや重い処理を分離したいときに活用。
methods
明示的に呼び出したい関数を定義する。メソッドは呼び出すたびに実行され、キャッシュはされない。

「常に最新の結果を返すために何度でも実行したいロジック」は methods 、「計算結果をキャッシュしたい・依存関係が変わらない限り再計算したくないロジック」は computed を利用すると効率的です。

基本的な使い方

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

methods に定義したメソッドはテンプレート内で以下のように使用します。例として、ボタンをクリックしたときにメソッドを呼び出すコードを見てみましょう。

現在のカウント: {{ count }}

HTML

<div id="app">
	<button @click="incrementCount">Count Up</button>
	<p>現在のカウント: {{ count }}</p>
</div>

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

	app.mount('#app');
</script>

複数のパラメータを渡す

テンプレート側でメソッド呼び出しにパラメータを指定することもできます。

HTML

<template>
	<div>
		<button @click="addToCart(item, quantity)">カートに追加</button>
	</div>
</template>

<script>
export default {
	data() {
		return {
			item: { id: 1, name: 'サンプル商品' },
			quantity: 3
		}
	},
	methods: {
		addToCart(product, num) {
			// ここで product と num にアクセスできる
			console.log(product, num)
			// 何らかのロジックを実行
		}
	}
}
</script>

このように、テンプレートから任意の引数を渡して処理を細かく制御できます。

高度な使い方・ベストプラクティス

メソッドのスコープに注意

methods 内での this はコンポーネントインスタンスを示しますが、アロー関数を使う場合の書き方には注意が必要です。例えば、以下のように書くと this が期待したオブジェクトを指さない可能性があるため、基本的にはメソッドには通常の関数定義(function) を使うのが安全です。

JavaScript

methods: {
	// 推奨: 通常の関数定義
	doSomething() {
		console.log(this) // this はコンポーネントインスタンス
	},

	// 注意: アロー関数では this が変わる可能性
	doSomethingArrow: () => {
		console.log(this) // ここでの this はコンポーネントではないかもしれない
	}
}

あえてアロー関数を使う場合は、this を使用しない純粋なユーティリティ的関数に限る、などの方針を明確にしておくとトラブルを避けられます。

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

Vue.js のコンポーネントには様々なライフサイクルフック(created, mounted, updated など)がありますが、これらのフックから methods を呼び出すことで、コンポーネントのライフサイクルに応じた処理をまとめることができます。例えば、コンポーネントがマウントされた直後に外部APIを呼んでデータを取得したい場合は以下のように書きます。

JavaScript

export default {
	data() {
		return {
			items: []
		}
	},
	methods: {
		async fetchData() {
			const response = await fetch('https://api.example.com/data')
			this.items = await response.json()
		}
	},
	async mounted() {
		await this.fetchData()
	}
}

このようにmethods を使い回す設計にすることで、ライフサイクルフックのみならず、ボタンクリックなど他のタイミングからも同じ処理を呼び出すことが可能です。

非同期処理とエラーハンドリング

外部APIコールなどで非同期処理を行う際には、methods を async/await で定義するとコードの見通しがよくなります。また、エラー処理を一箇所にまとめておくと可読性が向上します。

JavaScript

methods: {
	async fetchData() {
		try {
			const response = await fetch('https://api.example.com/data')
			if (!response.ok) throw new Error('HTTPエラー')
			this.items = await response.json()
		} catch (e) {
			console.error(e)
			this.errorMessage = 'データ取得に失敗しました'
		}
	}
}

エラーが発生した場合に、メソッド内でログの出力やステートへの代入を行い、エラー状態をUIに反映させることでユーザーにわかりやすく通知できます。

ミックスインやコンポジションAPIとの使い分け

Vue 2 系統でよく使われるミックスイン機能や、Vue 3 で加わったコンポジションAPI (setup) でもロジックを分割・共有できますが、methods はあくまでオプションAPIにおけるコンポーネントインスタンス上のメソッド集です。

ミックスイン
複数コンポーネントで共通化したい methods を一括定義
コンポジションAPI
setup() 関数の中にメソッドを定義し、return してテンプレート内で呼び出す

開発するプロジェクトの規模やチームの方針によって、methods とコンポジションAPIを使い分けることになります。大規模プロジェクトではロジックの分離・再利用性を高めるためにコンポジションAPIが推奨されるケースが多いですが、既存プロジェクトや小規模・単純なプロジェクトでは従来の methods を使った書き方でも十分な場合が多いでしょう。

実践サンプル:フォームのバリデーション

ここでは中級者以上でも参考になるような、入力フォームのバリデーションを methods で行う例を紹介します。

コンポーネント例

HTML

<template>
	<div>
		<form @submit.prevent="onSubmit">
			<div>
				<label>ユーザー名:</label>
				<input v-model="username" type="text" />
				<span v-if="errors.username" class="error">{{ errors.username }}</span>
			</div>
			<div>
				<label>パスワード:</label>
				<input v-model="password" type="password" />
				<span v-if="errors.password" class="error">{{ errors.password }}</span>
			</div>
			<button type="submit">送信</button>
		</form>
		<p v-if="submitMessage">{{ submitMessage }}</p>
	</div>
</template>

<script>
export default {
	data() {
		return {
			username: '',
			password: '',
			errors: {
				username: null,
				password: null
			},
			submitMessage: ''
		}
	},
	methods: {
		onSubmit() {
			// バリデーションチェック
			if (this.validateForm()) {
				// バリデーションOKの場合の処理
				this.submitMessage = 'フォームが正常に送信されました'
			}
		},
		validateForm() {
			// エラー情報を初期化
			this.errors.username = null
			this.errors.password = null
		
			let isValid = true
		
			// ユーザー名のバリデーション
			if (this.username.trim().length < 3) {
				this.errors.username = 'ユーザー名は3文字以上で入力してください'
				isValid = false
			}
		
			// パスワードのバリデーション
			if (this.password.trim().length < 6) {
				this.errors.password = 'パスワードは6文字以上で入力してください'
				isValid = false
			}
		
			return isValid
		}
	}
}
</script>

<style scoped>
.error {
	color: red;
}
</style>

この例のポイント

  1. @submit.prevent="onSubmit" でフォームの送信をフックし、onSubmit() メソッドをコール。
  2. validateForm() メソッドで各入力項目をチェックし、エラーの場合はメッセージを格納。
  3. errors オブジェクトを使うことで、エラーがある項目のみテンプレートでエラーメッセージを表示。
  4. バリデーションOKの場合は submitMessage を表示するなど任意の処理を実行。

このように、form のバリデーションロジックを methods にしっかり分割することで、可読性と保守性が高いコンポーネントを実現できます。さらに、複数フォームがある場合は、このバリデーションロジックをミックスインやコンポジションAPIでまとめると、より再利用性が高まります。

パフォーマンスと注意点

キャッシュされない点

methods で定義されたメソッドは、呼び出されるたびに実行されます。大量の計算が必要な処理や、何度も呼び出すロジックにおいてパフォーマンスに影響が出る場合、computed プロパティや外部ライブラリなどの活用を検討しましょう。

大きくなりすぎるロジックの分割

methods が肥大化しすぎると、コンポーネントの可読性が低下します。Vuex などのステート管理ライブラリを使用したり、コンポジションAPI・ミックスインでロジックを分割することを検討する必要があります。たとえば、外部APIの呼び出しロジックや汎用的なユーティリティ関数はコンポーネント外に切り出し、methods ではそれらを呼び出すだけにするのも一つの手法です。

まとめ

methods は Vue.js のコア要素であり、学び始めの段階から必ず触れる機能です。基本的な書き方から応用まで理解し、プロダクションレベルで活用するために、イベント駆動・データ操作・バリデーション・外部APIコールなどの具体的なユースケースを押さえておくと良いでしょう。

初学者の方はまずはシンプルなメソッドで慣れ、中級者以上の方はプロジェクトの設計指針やリファクタリングの観点から最適な方法を模索してみてください。きっと Vue.js 開発の幅が大きく広がるはずです。