前回はこちら
進め方
- タロットカードのデータをTypeScriptで配列にする ✅
- その中からランダムに1枚選ぶロジックを書く 👈今回はこれ
- 結果を表示する画面を作る(1ページ)
- カードごとに画像を表示してみる
- NuxtLinkでページ遷移(トップ→結果ページ)
- デザインを整える
- 応用:今日の運勢APIを取り入れてみる
- データの組み合わせで文章を作る
ステップ2.用意したカードの中からランダムに1枚選ぶロジックを書く
ざっと雛形。
<template>
<div class="p-fortune-contents">
<h1>タロット占い🔮</h1>
<button @click="drawCard">カードを引く</button>
<div class="p-results">
<h2>今日の運勢</h2>
<div class="p-results-card">
<p>カードの番号</p>
<p>カードの名前</p>
<p>カードの内容</p>
</div>
</div>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
「今日の運勢」の下に引いたタロットカードの情報を入れたい。→refを使う!
▼refの型付け
TSでrefを使うので、下記の公式ドキュメントの【refの型付け】を参考にする。
自分で考えて書いてみたが、GPTに聞いたら修正箇所の指摘が入った。
// 間違い
const selectedCard: Ref<number | string > = ref(null)
// ↓
// 修正後
const selectedCard: Ref<number | string | null> = ref(null)
ref(null) と書いてるのに、型には null が含まれてない
<考え方>
-
ref(null) は「初期値として null を入れる」という意味
-
Ref は「中に number か string しか入らない箱」という意味
▼ランダムにカードを1枚引く関数 drawCard()
を作る
このようなボタンを作った。
<button @click="drawCard">カードを引く</button>
<やりたいこと>
- ボタンを押下したら
drawCard
が動く -
tarotCards
からカードをランダムに一枚引く(Math.random
を使う) - 表か裏かをランダムに決める
- 引いたカードのid、名前、内容(表か裏のどちらか)を「今日の運勢」の下に表示させる
Math.random
を使うんだろうな、ということはわかったけど、実際の書き方が全然思い浮かばなかった。。😢
GPTにレクチャーをお願いした。
①Math.random() は 0 以上 1 未満の「小数」を返してくれる関数
Math.random() // 0.2857 や 0.9991 や 0.0032 のような数
②これを使ってインデックス番号を作る!
たとえばカードが 22枚あるなら、配列のインデックスは 0 〜 21 。
const index = Math.floor(Math.random() * 22)
- Math.random() * 22 → 0〜21.999...
- Math.floor(...) → 小数点以下を切り捨てて、0〜21の整数になる!
③ tarotCards.length
で枚数を自動で取得(22って決め打ちしない)
(今回はタロットだから決められた枚数ではあるけど)
const index = Math.floor(Math.random() * tarotCards.length)
const card = tarotCards[index]
これらを drawCard
関数として使うので
// カードを一枚選ぶ関数 drawCard
function drawCard () {
const index = Math.floor(Math.random() * tarotCards.length)
const card = tarotCards[index]
selectedCard.value = card
}
ここでTSエラーが出た。
型 'TarotCard' を型 'string | number | null' に割り当てることはできません。
これは、宣言している selectedCard の型は
const selectedCard: Ref<string | number | null> = ref(null)
↑こうなっているけど、実際に代入してる card は TarotCard 型
のオブジェクト
export const tarotCards: TarotCard[] = [
{
id: 0,
name: '愚者(The Fool)',
normalMeaning: '自由、冒険、無限の可能性',
reverseMeaning: '無計画、不安定、軽率',
},
selectedCard
の宣言を修正する。
<script setup lang="ts">
import { tarotCards, TarotCard } from '@/data/tarotCards'
import { ref, type Ref } from 'vue' // ref型を使う
// 選ばれたカード の型付け
// const selectedCard: Ref<number | string | null> = ref(null);
const selectedCard: Ref<TarotCard | null> = ref(null)
// カードを一枚選ぶ関数 drawCard
function drawCard() {
const index = Math.floor(Math.random() * tarotCards.length)
const card = tarotCards[index]
selectedCard.value = card
}
</script>
そうすると、またTSエラーが出た。。
'TarotCard' は型であり、'verbatimModuleSyntax' が有効であるときは、型のみのインポートを使用してインポートされる必要があります。
調べたら、TypeScript の「型は型だけとしてインポートすること」 というルールによるもの。
import部分を修正する。
import { tarotCards, type TarotCard } from '@/data/tarotCards'
次は引いたカードの内容を表示させる!