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.
Vue.js を使った開発では、「methods」が頻繁に登場します。methods はコンポーネントに定義されたメソッド(関数)の集合であり、ユーザー操作やイベントなどを契機として呼び出されるロジックをまとめる場所として重宝されます。
Vue.js(オプションAPI)においては、コンポーネント内で動的に処理を行いたい時に使用するプロパティが methods
です。具体的には、
JavaScript
export default {
// ...
methods: {
methodA() {
// 処理内容
},
methodB(param) {
// パラメータを受け取り、何らかの処理を行う
}
}
}
のようにオブジェクトとして定義し、その中に自由にメソッドを定義していきます。テンプレート(HTML)でのイベントハンドリングや、コンポーネント内の任意の場所から呼び出せるため、非常に便利です。
data
や state
に反映Vue.js には、コンポーネント内の状態変化を扱うために、主に以下の 3 つの仕組みが用意されています。
「常に最新の結果を返すために何度でも実行したいロジック」は 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>
@click="incrementCount"
とすることで、ボタンがクリックされたときに incrementCount()
が呼び出され、count
を 1 増加させます。this
は Vue インスタンスそのもの(より正確にはコンポーネントのインスタンス)を指しますので、this.count
のようにデータへアクセス可能です。テンプレート側でメソッド呼び出しにパラメータを指定することもできます。
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()
}
}
mounted()
フック内で this.fetchData()
を呼び出し、コンポーネントが表示された直後にデータを取得。this.items
にセットして、テンプレートへ反映させる。このように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に反映させることでユーザーにわかりやすく通知できます。
Vue 2 系統でよく使われるミックスイン機能や、Vue 3 で加わったコンポジションAPI (setup
) でもロジックを分割・共有できますが、methods はあくまでオプションAPIにおけるコンポーネントインスタンス上のメソッド集です。
開発するプロジェクトの規模やチームの方針によって、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>
この例のポイント
@submit.prevent="onSubmit"
でフォームの送信をフックし、onSubmit()
メソッドをコール。validateForm()
メソッドで各入力項目をチェックし、エラーの場合はメッセージを格納。errors
オブジェクトを使うことで、エラーがある項目のみテンプレートでエラーメッセージを表示。submitMessage
を表示するなど任意の処理を実行。このように、form のバリデーションロジックを methods にしっかり分割することで、可読性と保守性が高いコンポーネントを実現できます。さらに、複数フォームがある場合は、このバリデーションロジックをミックスインやコンポジションAPIでまとめると、より再利用性が高まります。
methods
で定義されたメソッドは、呼び出されるたびに実行されます。大量の計算が必要な処理や、何度も呼び出すロジックにおいてパフォーマンスに影響が出る場合、computed
プロパティや外部ライブラリなどの活用を検討しましょう。
methods が肥大化しすぎると、コンポーネントの可読性が低下します。Vuex などのステート管理ライブラリを使用したり、コンポジションAPI・ミックスインでロジックを分割することを検討する必要があります。たとえば、外部APIの呼び出しロジックや汎用的なユーティリティ関数はコンポーネント外に切り出し、methods ではそれらを呼び出すだけにするのも一つの手法です。
methods は Vue.js のコア要素であり、学び始めの段階から必ず触れる機能です。基本的な書き方から応用まで理解し、プロダクションレベルで活用するために、イベント駆動・データ操作・バリデーション・外部APIコールなどの具体的なユースケースを押さえておくと良いでしょう。
初学者の方はまずはシンプルなメソッドで慣れ、中級者以上の方はプロジェクトの設計指針やリファクタリングの観点から最適な方法を模索してみてください。きっと Vue.js 開発の幅が大きく広がるはずです。