1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vueを勉強していたら、`class`があまり出てこないことに気が付いた

1
Posted at

JavaScriptを勉強していたときは、classという言葉をよく見かけました。ゲームなら、プレイヤーのHPやお金をまとめるものとして考えると分かりやすい、と聞いたこともあります。

ところがVueを触り始めると、よく出てくるのはref、関数、v-ifv-forです。classを使う場面があまり出てこないことに気が付いたので、「Vueでは何を使って画面を作っているのか」を自分なりに整理してみます。

フロント側の画面を作れるようになりたいので、まずは「ボタンを押すと何が変わり、画面がどう変わるのか」を追えるようになりたいです。

まだ途中段階なので、勘違いなどあれば教えていただけるとうれしいです。

今日やったこと

Vueでは、classよりも「変わる値」と「画面表示」のつながりを意識する場面が多いと感じました。

ゲームの画面でHPを表示したいとします。HPが減ったら、画面のHPも変わってほしいです。

Vueでは、こういう「変わる値」をrefで持てます。Vueは状態の変化を追いかけ、変化があれば画面の表示を更新します。 Vue.js公式ドキュメント も少しずつ見返しています。 ja.vuejs

キャラクター 「ゲームでいうと、HPの数字が変わったら、ステータス画面の表示もちゃんと書き換えてくれる感じだね。」

次のコードでは、「10ダメージを受ける」ボタンを押すと、HPが30から20へ変わります。

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

// 画面に表示するHPを、Vueが追いかけられる形で用意する
const hp = ref(30)

function takeDamage() {
  // refの中の値を変えるときは、JavaScript側では.valueを付ける
  hp.value -= 10
}
</script>

<template>
  <section>
    <!-- テンプレートでは.valueを書かず、そのままhpを表示できる -->
    <p>HP: {{ hp }}</p>

    <!-- ボタンを押すと、HPを減らす関数が動く -->
    <button @click="takeDamage">
      10ダメージを受ける
    </button>
  </section>
</template>

この例では、classを書かなくても「HPを覚える」「ボタンを押したらHPを変える」「画面の数字を変える」ができます。

つまずいたところ

refがあれば、ゲームのルールも全部自動で守ってくれるのかと思いました。

たとえば、回復薬を使うとき、HPが最大HPを超えてはいけません。HPが20、最大HPが30のときに、20回復してもHPは40ではなく30になってほしいです。

キャラクター 「`ref`はHPを画面に見せてくれる仕組み。HPをどこまで回復できるかは、自分で決める必要があるんだね。」

refは、値が変わったときに画面を変えるためのものです。「最大HPを超えない」というルールは、関数の中に書きます。

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

// 今のHPと、HPの上限をそれぞれ用意する
const hp = ref(20)
const maxHp = ref(30)

function heal() {
  // Math.minは、小さいほうの数字を選ぶ
  // 20 + 20 は40だが、最大HPの30を超えないようにする
  hp.value = Math.min(hp.value + 20, maxHp.value)
}
</script>

<template>
  <section>
    <p>HP: {{ hp }} / {{ maxHp }}</p>

    <!-- ボタンを押すと、最大HPを超えない回復が行われる -->
    <button @click="heal">
      回復薬を使う
    </button>
  </section>
</template>

この書き方なら、classを使わなくても「回復した後のHPは最大30」というルールを書けます。

今の理解(メモ)

今の自分の頭の中では、Vueは「ゲームの画面を更新する係」、関数は「ゲーム内で何をするかを書く係」に近いです。

  • refは、HPや所持金のように、画面で変わる値を覚えるためのもの
  • 関数は、ダメージを受ける、回復薬を使う、アイテムを買うなどの処理を書くもの
  • v-ifは、条件によって表示を変えるもの
  • v-forは、データの数に合わせて同じ形を並べるもの
  • computedは、HPの割合のように、別の値から計算して作るもの
  • classは、たくさんの値やルールをまとめるJavaScriptの書き方のひとつ

たとえば、HPが0になったら「ゲームオーバー」と表示したいとします。v-ifを使うと、HPが0のときだけ文章を表示できます。v-ifは、条件が正しいときだけ画面に表示するための書き方です。 ja.vuejs

<template>
  <section>
    <!-- hpが0のときだけ、この文章を画面に出す -->
    <p v-if="hp === 0">
      ゲームオーバー
    </p>
  </section>
</template>

ゲームの持ち物一覧のように、データの数に合わせて表示を増やしたいときはv-forを使えます。画像解析結果や写真のカード一覧も、同じような形で並べられそうです。Vueでは、配列をもとに一覧を表示するときにv-forを使います。 ja.vuejs

キャラクター 「持ち物の数だけ一覧に並ぶ仕組みは、画像や解析結果のカードを並べるときにも使えそう。」

今は、Vueコンポーネントをclassで書くよりも、<script setup>の中でrefと関数を使う書き方から覚えていこうと思います。

次にやりたいこと

まずはclassを使わず、Vueで画面が変わる流れを小さく試したいです。

  • HPをrefで持ち、ダメージと回復のボタンを作る。クリックすると数字がどう変わるか確かめたい
  • HPが0になったら「ゲームオーバー」と表示する。v-ifで表示が切り替わる流れを見たい
  • HPが最大値なら、回復ボタンを押せなくする。:disabledでボタンが変わることを試したい
  • アイテム名を配列で用意し、v-forで一覧に並べる。持ち物一覧のような画面を作ってみたい
  • 同じ考え方で、画像解析結果や写真をカード一覧として並べる。ゲームの例から実際に作りたい画面へつなげたい

今日の整理

Vueでは、画面に表示する値と、値を変える処理を近くに書けるように感じました。

言葉 今の理解 ゲームでの例 画面で起きること
ref 変わる値を覚える HP、所持金 数字が変わると表示も変わる
関数 値を変える処理を書く ダメージ、回復 ボタンを押すとHPが変わる
v-if 条件で表示を出し分ける HPが0ならゲームオーバー 文章や画面部品が出たり消えたりする
v-for データの数だけ表示を繰り返す 持ち物一覧 アイテムやカードが並ぶ
computed 値から別の値を計算する HPの割合 ゲージやメッセージを変えられる
class 値とルールをまとめる書き方 HP・お金・経験値の管理 今は無理に使わなくてよさそう

おわりに

Vueでclassがあまり出てこないことが気になっていましたが、Vueではまず「画面に何を表示するか」「ボタンを押したら何が変わるか」を考える場面が多いのだと少し分かってきました。

今は、refと関数で小さなゲーム画面のようなものを作り、値が変わると画面も変わる流れを追っていきたいです。そのあとで、画像解析結果を見やすく並べる画面や、写真を検索できる一覧画面にもつなげてみたいと思います。

学習中の内容なので、勘違いや理解不足もあると思います。もし気になる点があれば教えてもらえるとうれしいです。

 注意事項
 本ブログに掲載している内容は、私個人の見解であり、
 所属する組織の立場や戦略、意見を代表するものではありません。
 あくまでエンジニアとしての経験や考えを発信していますのでご了承ください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?