Vue.jsで関数を自由自在に動かそう。

僕がVue.jsに触れ始めて1年が経ちました。
今ではかなり仲のいいお友達であるVue.jsくんも、出会った頃はなかなか心を開いてくれませんでした。
僕が「この関数を実行して」とお願いしたつもりでも、Vue.jsは一向に言うことを聞いてくれません。

なぜでしょう、答えは単純です。僕のお願いの仕方が悪かったのです。

Vue.js はとても素直で、お願いしたことはちゃんとやってくれます。
ただし、Vue.js が理解できる“お願いの仕方”で伝えないといけません。
正しい敬語で話しても、へりくだってお願いをしても、ダメなものはダメなのです。

今回は、今日Vue.jsを始めたあなたが、僕と同じ目に合わないように、Vue.jsへ正しく関数の実行をお願いする方法について解説していきます。

※本記事ではJavaScriptのVue3、CompositionAPIを前提とした解説です。仕組みや仕様は他バージョン、他APIでも参考にしていただけますが、具体的なソースコードの記述は異なる部分もありますので、ご注意ください。
 

まずは、関数を実行するために、Vue.jsが用意してくれている仕組みをざっと紹介します。

・methods

・computed

・onMounted

・watch

です。

これらは、同じ「関数を実行する仕組み」です。
では、違いはどこにあるのでしょうか?

違いは、「関数を実行するきっかけ」にあります。

今回はこの4兄弟の中から、methods / computedについて初心者の方にもわかりやすく、詳しく解説していきます。

◆ methods:呼びたいときに呼ぶ。

methods は、先ほどの 4 兄弟の中で最もシンプルです。

僕もまずは1番にこれを理解しました。

「この関数を実行して」とお願いすれば、その瞬間に指定した関数を実行してくれます。

※実のところComposition API には Options API のような “methods” という専用の書き場所はありません。この記事では、初心者の方が理解しやすいように、「呼んで実行する関数」という意味で  Options APIで使用されている “methods”という名前を使っています。

◇ 実行タイミングをコードで確認しよう

例えば、こんなmethodsがあったとします。

const sayHello = () => {
  console.log("こんにちは")
}

これは、sayHello を呼び出すと「こんにちは」という文字列がログに出力される関数です。

methods は名前の通り “メソッド(呼び出される関数)” です。
Vue.js の中で「自分で呼び出す」関数を書くために使われます。

●呼び出し方①:ほかの関数の中で呼ぶ

一番わかりやすいと思います。

const doSomething = () => {
 sayHello()   // ← ここで呼び出す
}

このように、別の関数の中で sayHello() を書けば、その関数(doSomething)が実行されたタイミングでsayHelloが実行されます。

●呼び出し方②:テンプレート(HTML)から呼ぶ

これはフロントエンドのフレームワークならではの呼び出し方ですね。

Vue.js のテンプレートでは、イベント(ユーザー操作や入力)と組み合わせて関数を呼び出すことができます。

<button @click="sayHello">
 ここをクリック
</button>

このように書けば、ボタンが押された瞬間に sayHello() が実行されます。

呼び出し側の関数が実行されたり、ボタンが押されたタイミングで関数を実行することができます。

● methodsまとめ

一言でいうと、methodsは「呼んで実行する関数」です。

・呼び出し側の関数が実行されたタイミング

・ボタンが押されたタイミング

・イベントが発生したタイミング

上記のようなタイミングで関数を使いたいときにはmethodsを利用しましょう。

◆ computed:値が変わったときだけ再計算される「算出プロパティ」

今まで『関数』という言葉を使ってきましたが、computed はある値から自動で計算される“もうひとつの値”を作る仕組みです。
見た目は変数のように扱えますが、内部では依存している値が変わったときだけ再計算される処理が動いていて、その結果がリアクティブな値として返されます。

…….???

ですよね。分かります。
僕がVueを始めた直後に同じことを言われても、きっと同じことを思うでしょう。
僕もcomputedを理解するまでが一番時間がかかりました。

ここからは、先ほどの説明を噛み砕いて解説していきます。

◇ まずは実行タイミングを言語化しよう。

例えばこんなcomputedがあったとします。

const buddy = ref(0)

const doubleByComputed = 
 computed(() => buddy.value * 2)

※const buddy = ref(0)の部分は、refというまた別の仕組みです。
refというのは「中身が書き換わるリアクティブな変数」を作る仕組みです。ここでは「buddy は値が変わる変数なんだな」くらいの理解で大丈夫です。

この computed

const doubleByComputed = computed

は、buddy の値を 2 倍にして

(() => buddy.value * 2)

doubleByComputed に返す仕組みです。

const doubleByComputed = 
 computed(() => buddy.value * 2)

では、この処理

(() => buddy.value * 2)

は、いつ実行されるのでしょうか?
答えは、「buddy の中身が変わったタイミング」です。
この、「buddy の中身が変わったタイミング」というのが、前述した「依存している値が変わったとき」ということになります。

“依存している値”というはcomputedの値を求めるために必要な値ということです。

今回の場合だとdoubleByComputedの計算に必要な値は”buddy”ですね。

◇ 実行タイミングをコードで確認しよう

具体的にソースコードを追ってcomputedの実行タイミングと注意点を確認しましょう。

下記のようなmethodsの関数があったとします。

const getCountDifference = () => {
 const oldValue = doubleByComputed  // 1

 buddy.value =+ 2      // 2

 const newValue = doubleByComputed  // 3

 return newValue - oldValue         // 4
}

ここで問題です。この中で、doubleByComputedの中の処理が実行されるタイミングは1~4のうちどこでしょうか?


答えは2の

"buddy.value =+ 2 "

です。

この行で「doubleByComputed を求めるために必要な値(buddy)」が変更されていますね。
その瞬間が「依存している値が変わったとき」 であり、computed の処理が再実行されるタイミングになります。

● 1や3の行はどうなる?

1や3の行でもcomputedの名前を記述しています。methodsだったらここで処理が実行されそうですよね。
ここが computed の少しややこしいポイントです。

const oldValue = doubleByComputed

このタイミングでは計算処理は再実行されません。代わりに「前回計算した結果(キャッシュされた値)」が返却されます。

● 実際の値の変化を追ってみる

仮にbuddyの値が1だったとします。

const buddy = ref(1)

const doubleByComputed = 
 computed(() => buddy.value * 2)

その場合、doubleByComputedの値は 2 になります。
ですから、

const oldValue = doubleByComputed

では、oldValueに2が入ります。

その後

buddy.value =+ 2

で、buddyの値は3になります。

すると
doubleByComputed は 6 に再計算され、

const newValue = doubleByComputed

newValueに6が入るわけです。

結果として

return newValue - oldValue

では、4 がreturnされます。 

この直後にもう一度getCountDifferenceを実行してみるとどうなるでしょう。
buddyの値はすでに3なので、今度はoldValueに6が入りnewValueには”5 * 2″の結果の10が入ります。

その後、

return newValue - oldValue

で、4 が帰るというわけですね。

● computedまとめ

一言でいうとcomputedは、「必要なときだけ計算する賢い値」です。

・computed は「自動で計算されるもうひとつの値」

・依存している値が変わったときだけ再計算される

・それ以外のときは前回の結果(キャッシュ)を返す

◆ まとめ

この記事を読んでVue.jsくんと仲良くする方法が何となくつかめたでしょうか。

methods は「呼んだら実行される関数」、
computed は「必要なときだけ計算される賢い値」

この2つを理解すると、Vue.js の中で「どのタイミングで処理が動くのか」を自分でコントロールでき始めます。
特に computed は、依存している値が変わったときだけ再計算されるため、無駄な処理を減らしつつ、常に最新の計算結果を参照できる便利な仕組みです。
うまく使いこなせれば、コーディングのレベルが1段上がったといっていいでしょう。

ただし、Vue.js が用意している「関数を実行するきっかけ」はまだ他にもあります。

値の変化に反応して処理を実行する watch、
コンポーネントが画面に表示された瞬間に処理を実行する onMounted。
先ほど紹介したうちの残りの2兄弟ですね。

※もちろん他にもあります。

次の記事では、この watch と onMounted を解説していきます。

この記事があなたのVue.jsに対する理解を少しでも深めるきっかけになれば幸いです。

最後になりますが、最後まで記事を読んでくださりありがとうございます。

こちらのブログサイトには、ほかにも参考になる記事がたくさんありますので、ぜひそちらもご覧ください。