Vue.js

Vue.js練習問題

コードを先に書き、答えを開いて結果と理由を確認しましょう。

Vue.js入門の講座一覧

01

カウンターを作る

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を使います。

02

未完了件数を表示する

Todo配列から未完了の件数だけを表示してください。件数を別のstateとして手動管理しないことが条件です。

解答例を表示
解答コードVUE
const remaining = computed(() =>
  todos.value.filter(todo => todo.done === false).length
)

todosから導ける値はcomputedにします。Todoの完了状態が変わると自動で再計算されます。

03

商品一覧を描画する

id、name、priceを持つ配列をv-forで表示し、商品名と価格を出してください。keyには何を指定しますか。

解答例を表示
解答コードVUE
<li v-for="product in products" :key="product.id">
  {{ product.name }}: {{ product.price }}円
</li>

idのように項目を一意に特定できる値をkeyにします。配列のindexは並べ替えや削除に弱いので、特別な理由がない限り避けます。

04

フォームを検証する

タイトルが空欄ならエラー、1文字以上なら成功メッセージを表示するフォームを作ってください。

解答例を表示
解答コードVUE
const title = ref('')
const message = ref('')
function submit() {
  if (title.value.trim() === '') {
    message.value = 'タイトルを入力してください'
    return
  }
  message.value = '登録しました'
}

空白だけの入力も空欄とみなすため、trimを使います。ブラウザー側の検証は補助であり、サーバー側の検証も必要です。

05

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)
}

データを持つ親が変更を担当し、子は出来事を伝えるだけにすると、責務が分かれます。

06

小さなアプリの設計

買い物リストを作るとして、次の要件をどの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)
}