最終更新:

Vueの始め方 — refとcomputedで買い物の合計を表示しよう


数量が変わると、合計も変わる

ひよこのお買い物1個120円数量:3個合計:360円1個ふやすref数量を持つcomputed合計を計算クリックで数量を更新
初期表示は1個・120円。2回押した後が3個・360円です。図は見た目の例で、動くコードは本文のApp.vueです。
🎚 難易度 ★☆☆ 初心者向け
⏱ 学習時間の目安 読むだけ10分、環境構築込み30〜60分
📚 前提知識 HTMLの基本とJavaScriptの変数・関数を知っていること・Node.jsの要件を確認し、ターミナルを使えること
✅ このガイドで学べること
  • 公式create-vueでアプリを作成する
  • App.vueの3つのブロックを知る
  • refとcomputedで数量と合計を持つ
  • クリック後の画面更新と本番ビルドを確認する
ひよこ ひよこ
数量を増やすと合計も変わるページを作りたいな。Vueでできる?
ペンギン先生 ペンギン先生
できるよ。VueはJavaScriptのUIフレームワークで、データと画面を結び付けて書けるんだ。今回は1個120円の商品を例に、数量と合計が一緒に変わる小さなアプリを作ろう。
ひよこ ひよこ
JavaScriptでtextContentを書き換えるのとは違うの?
ペンギン先生 ペンギン先生
Vueでは画面に使うデータを用意し、テンプレートにその表示方法を書くよ。データが変わると関連するDOMの更新をVueが行うんだ。毎回自分で表示先を探して書き換える部分を減らせるね。
ひよこ ひよこ
環境はどう作ればいい?
ペンギン先生 ペンギン先生
公式のnpm create vue@latestを使おう。確認時点のNode.js要件は22.18.0以上の22系列、または24.12.0以上だよ。対応LTSの更新版を選び、追加機能は今回いったん付けずに最小構成で始めよう。
ひよこ ひよこ
App.vueのscript、template、styleはそれぞれ何?
ペンギン先生 ペンギン先生
script setupはデータや処理、templateは画面、styleは見た目を書くところだよ。このように一つの.vueファイルへまとめる形式がSFC。まずはこの3つの役割を対応付ければ大丈夫。
ひよこ ひよこ
refっていう関数は何をしているの?
ペンギン先生 ペンギン先生
変化を追跡する値を作るよ。script内ではquantity.valueで中身を読み書きする。今回のテンプレートに置いたトップレベルのrefは自動で取り出されるから、quantityと書けるんだ。どの入れ子のrefも常に同じ扱い、というわけではないよ。
ひよこ ひよこ
合計も自分で毎回更新するの?
ペンギン先生 ペンギン先生
computedでquantity.value * unitPriceと定義すれば、依存する数量から計算できるよ。クリックでは数量だけを増やし、合計の更新はその依存関係に任せる。別々に更新して数字が食い違うミスを減らしやすいね。
ひよこ ひよこ
ボタンの@clickはどういう意味?
ペンギン先生 ペンギン先生
v-on:clickの短い書き方で、クリック時の処理を指定するよ。例ではquantityを1増やす。2回押したら数量3・合計360円になるか確認しよう。ページの再読み込みで数量1に戻るのは、この例では正常だよ。
ひよこ ひよこ
次に学ぶならどこかな?
ペンギン先生 ペンギン先生
入力を扱うv-model、リストを表示するv-for、部品へ分けるコンポーネントへ進もう。Options APIも有効な書き方だよ。今回のComposition APIが唯一の正解だと思わず、チームや教材の形式を確認するといいね。

最初のゴール:2回押すと3個・360円

HTMLとJavaScriptでボタンを動かしたことがあると、Vueが担当する部分を見つけやすくなります。JavaScript入門から進んでも構いません。

1. 公式ツールで最小のプロジェクトを作る

公式の確認時点のNode.js要件は ^22.18.0 || >=24.12.0。対応するLTS系列の更新版を用意し、次を実行します。

node --version
npm create vue@latest

プロジェクト名は my-vue-app にします。この例ではTypeScript・Router・Pinia・テストなどの追加機能を選ばない最小構成にします。作成後は次を実行します。

cd my-vue-app
npm install
npm run dev

表示されたローカルURLを開きましょう。ポートが使用中なら別の番号になることがあるため、常に5173と決めつけず、ターミナルを確認します。

2. src/App.vueを置き換える

<script setup>
import { ref, computed } from 'vue'

const unitPrice = 120
const quantity = ref(1)
const total = computed(() => quantity.value * unitPrice)
</script>

<template>
  <main>
    <h1>ひよこのお買い物</h1>
    <p>1個 {{ unitPrice }}円</p>
    <p>数量: {{ quantity }}個</p>
    <p aria-live="polite">合計: {{ total }}円</p>
    <button type="button" @click="quantity += 1">1個ふやす</button>
  </main>
</template>

<style scoped>
main { padding: 1rem; }
button { padding: 0.5rem 1rem; }
</style>

保存してブラウザを確認します。初期表示は1個・120円、2回押したら3個・360円です。生成テンプレートのグローバルCSSが残ると見た目は異なる場合がありますが、数量と合計は同じです。

scriptの.valueと、画面の更新を区別する

computed の中はJavaScriptなので quantity.value と書きます。テンプレートでは今回のトップレベルrefが展開されるため quantity のままで使えます。VueはDOM更新をまとめて次の更新タイミングへ送るので、JavaScriptで値を変えた直後の同じ処理中にDOMも必ず更新済みとは限りません。DOM更新後に処理する場合は nextTick を使う場面があります。

表示されない場合はApp.vueを編集したか、importのスペルやConsoleの最初のエラーを確認します。Missing script: devなら、作成したプロジェクトのフォルダにいるか確認しましょう。

公開用の確認は開発サーバーをCtrl+Cで止めてから npm run build、続いて npm run preview。実際の公開先への配置はホスティングの手順に従います。画面を分ける学習へ進むなら公式コンポーネントガイド、他との比較ならReact・Vue・Svelteへ。

参考資料

次に学ぶなら