カウンターを作る
ref(0)を使い、ボタンを押すと1ずつ増えるカウンターを作ってください。0未満にならない「減らす」ボタンも追加します。
解答例を表示
解答コードVUE
const count = ref(0)
function increment() { count.value += 1 }
function decrement() { if (count.value > 0) count.value -= 1 }前の値を読み取り、その値を変更する処理なので、refの.valueを使います。
未完了件数を表示する
Todo配列から未完了の件数だけを表示してください。件数を別のstateとして手動管理しないことが条件です。
解答例を表示
解答コードVUE
const remaining = computed(() =>
todos.value.filter(todo => todo.done === false).length
)todosから導ける値はcomputedにします。Todoの完了状態が変わると自動で再計算されます。
商品一覧を描画する
id、name、priceを持つ配列をv-forで表示し、商品名と価格を出してください。keyには何を指定しますか。
解答例を表示
解答コードVUE
<li v-for="product in products" :key="product.id">
{{ product.name }}: {{ product.price }}円
</li>idのように項目を一意に特定できる値をkeyにします。配列のindexは並べ替えや削除に弱いので、特別な理由がない限り避けます。
フォームを検証する
タイトルが空欄ならエラー、1文字以上なら成功メッセージを表示するフォームを作ってください。
解答例を表示
解答コードVUE
const title = ref('')
const message = ref('')
function submit() {
if (title.value.trim() === '') {
message.value = 'タイトルを入力してください'
return
}
message.value = '登録しました'
}空白だけの入力も空欄とみなすため、trimを使います。ブラウザー側の検証は補助であり、サーバー側の検証も必要です。
Propsとemitで削除する
子が受け取ったTodoのidをemitし、親がfilterで対象を除く構成を書いてください。
解答例を表示
解答コードVUE
// 子
const emit = defineEmits(['remove'])
emit('remove', todo.id)
// 親
function removeTodo(id) {
todos.value = todos.value.filter(todo => todo.id !== id)
}データを持つ親が変更を担当し、子は出来事を伝えるだけにすると、責務が分かれます。
小さなアプリの設計
買い物リストを作るとして、次の要件をどのstate・computed・コンポーネントに分けるか考えてください。
- 商品を追加・削除できる
- 合計金額を表示する
- 一覧と入力フォームを別コンポーネントにする
- 通信中と失敗を表示する
考え方と一例
商品配列は親またはstoreが所有し、合計はcomputed、入力はフォームコンポーネントのローカルstate、追加・削除はemit、通信状態はloading・error・successに分けます。最初からPiniaにするのではなく、1画面なら親子のProps・emitで始める方法も適切です。
設計のコード例VUE
const items = ref([])
const total = computed(() =>
items.value.reduce((sum, item) => sum + item.price, 0)
)
function addItem(item) {
items.value.push(item)
}