前回はAxiosでソード1本の情報を受け取り、成功なら .then()、失敗なら .catch() に進む流れを見てみました。今回はソードを複数受け取り、Vue 3の v-for で画面に並べています。文章だけでは自分でも追いきれなかったので、画面の切り替わりとデータの流れをMermaidの図にしながら整理しました。画面の動きを自分の言葉で説明できるようになりたい、というのが今の目的です。
まだ途中段階なので、勘違いなどあれば教えていただけるとうれしいです。
今日やったこと
Axiosで受け取った複数のソードを、本数に合わせて画面へ並べました。
前回受け取っていたのは、ソード1本の情報だけでした。今回は複数入った形にします。public/swords.json に置く想定です。
[
{ "id": 1, "name": "Iron Sword" },
{ "id": 2, "name": "Wood Sword" },
{ "id": 3, "name": "Silver Sword" }
]
ゲームで考えると、鍛冶屋から1本を受け取るのではなく、持ち物袋を開いて今ある装備を一覧で見る場面に近そうです。画面は最初から一覧が出ているわけではなく、3つの状態を行き来します。
![]() |
「3本あるなら画面にも3枚並んでほしいね。何本届くか分からないのに書けるのかな」 |
この3つの状態を上から順に扱いたかったので、async / await と try / catch で書いています。
<script setup>
// Axiosを使えるように読み込む
import axios from 'axios'
// onMountedは画面が表示された後に処理を始めるために使う
// refは画面に表示する値を覚えておくために使う
import { onMounted, ref } from 'vue'
// 受け取ったソード一覧を入れる箱
// 最初は0本なので、空の配列を入れる
const swords = ref([])
// 読み込み中かどうかを覚えておく
const isLoading = ref(true)
// 受け取れなかったときに画面へ出す文章
const errorMessage = ref('')
const loadSwords = async () => {
try {
// swords.jsonを取りに行き、データが届くまで待つ
const response = await axios.get('/swords.json')
// Axiosが受け取った中身はresponse.dataに入っている
swords.value = response.data
} catch {
errorMessage.value = 'ソード一覧を受け取れませんでした'
} finally {
// 成功でも失敗でも、読み込み中の表示は終わりにする
isLoading.value = false
}
}
// 画面が表示された後に読み込みを始める
onMounted(loadSwords)
</script>
<template>
<main>
<!-- データを待っている間だけ表示する -->
<p v-if="isLoading">持ち物袋を確認しています...</p>
<!-- 受け取れなかったときに表示する -->
<p v-else-if="errorMessage">{{ errorMessage }}</p>
<section v-else>
<h1>ソード一覧</h1>
<!-- swordsに入っている本数だけarticleを繰り返す -->
<article v-for="sword in swords" :key="sword.id">
<p>{{ sword.name }}</p>
</article>
</section>
</main>
</template>
図の3つの状態が、そのまま v-if / v-else-if / v-else に対応しています。読み込みが終わると待機中の文章が消え、ソード名が3行並びます。
つまずいたところ
await を書かないと何が起きるのか、言葉で説明できませんでした。
Axiosは、データそのものではなく「あとで結果を渡す約束」を返します。await を付けずに書くと、結果が届く前に次の行へ進んでしまいます。
![]() |
「頼んだ直後に受け取り口へ行っても、まだ何も置かれていないってことか」 |
待たない場合を、番号で追ってみます。
await を付けると、届いてから先へ進みます。番号の並びは同じでも、2番で一度止まる点が違います。
もう1つ迷ったのが、.then() と async / await を両方書く必要があるのかという点です。どちらもAxiosの結果を受け取るための書き方なので、同じ通信ではどちらかにそろえればよさそうだと今は考えています。
![]() |
「受け取り方が2種類あるだけで、受け取れるソードが増えるわけじゃないんだね」 |
前回は成功と失敗の分かれ道が横に見える .then() / .catch() が読みやすいと感じました。今回は状態が3つあるので、上から順に追える形を試しています。書き方の違いだけで結果が変わるわけではない、という理解でよいのかはまだ確認したい部分です。
今の理解(メモ)
届くまで待って箱へ入れ、その箱の中身を v-for が画面へ並べる、という流れとして見ています。
-
ref([])は、最初は空の持ち物袋。何本入るか決めずに用意しておく -
response.dataに、Axiosが受け取った一覧が入っている -
swords.valueが変わると、Vueが画面の表示も更新する(Vue.js公式ドキュメント) -
:key="sword.id"は、どのカードがどのソードなのかをVueが見分けるための番号 -
finallyは成功でも失敗でも通るので、読み込み中の表示を消す場所に向いている
この流れは、画像解析結果の一覧やアップロードした写真の一覧にも当てはめられそうです。待機中の表示を出しておき、届いたらカードを並べる形なら扱いやすい気がします。
次にやりたいこと
見るだけの一覧から、操作できる画面に近づけたいです。
- ソードが0本のときの表示を作る。空の配列でも
v-forが何も出さないことを確認したい - 各カードに「装備する」ボタンを付ける。押したソードを
refに入れ、選択中として画面に出したい - ボタンで一覧を読み込み直す。操作をきっかけに通信が走る流れを見たい
- 同じ一覧を
.then()/.catch()でも書き、自分にはどちらが読みやすいか見比べたい - ソードを画像解析結果に置き換え、ファイル名と判定結果をカードで並べたい
![]() |
「一覧が出せたなら、次は選んで装備欄に移すところが気になるね」 |
今日の整理
今日出てきたものを、1枚の図にまとめておきます。
用語ごとの利用イメージは、次のように見ています。
| 用語 | 利用イメージ | 次に確認したいこと |
|---|---|---|
ref([]) |
解析結果や写真の一覧 | 0本のときの画面表示 |
await |
一覧が届いてから表示 | 待たない場合の差の確かめ方 |
v-for |
カード一覧、検索結果 | 並び替えや絞り込み |
おわりに
何本届くか分からないデータをどう画面に出すのか、始める前は見当がつきませんでした。空の箱を先に用意して、届いたら入れて、あとは v-for に任せる形だと、思っていたより素直に書けました。図に番号を振って並べたことで、「待たないと空のまま進む」という部分も自分の中で少し形になった気がします。
フロント側を扱えるようになりたい理由は、オンプレで動かしている画像解析の結果を、もっと見やすい画面で扱いたいからです。一覧を出して、選んで、詳細を見るところまでつながれば、業務で作りたい画面にも近づけそうです。
学習中の内容なので、勘違いや理解不足もあると思います。もし気になる点があれば教えてもらえるとうれしいです。
注意事項
本ブログに掲載している内容は、私個人の見解であり、
所属する組織の立場や戦略、意見を代表するものではありません。
あくまでエンジニアとしての経験や考えを発信していますのでご了承ください。
