この記事について
Vueを学び始めたとき、
v-modelってなんのためにあるの?
使ったら何ができるようになるの?
と疑問に思う人は多いと思います。
この記事では、v-modelの使い方だとか詳しいことを説明するよりも前に理解しておく必要がある
「v-modelの存在理由」について説明します。
v-modelは便利機能というより、<input>
タグに最低限必要なもの
v-model以外のVueのディレクティブ v-if
や v-for
などと違って、
v-modelは便利な機能というイメージではありません。
どちらかというと「まともな入力欄として動かすために最低限必要なもの」
という認識でいたほうが、理解しやすいと思います。
Vueでは動的なデータは変数で管理する必要がある
Vueを使う場合、動的なデータ(ユーザーの入力やクリック等の操作によって表示が変わる部分)は
コンポーネントのdataとして変数で管理することになります。
<script>
export default {
data:()=>({
dataA: "",
dataB: "",
dataC: "",
}),
}
</script>
ピュアなHTMLを書いていたときは、<input>
タグを書けば、
入力した値は自動的に管理されていて、
なにも指定しなくても「文字の入力ができる」「文字を消したりできる」「文字を書き換えることができる」という機能は備わっていました。
しかし、Vueではそれだけではなく、
「文字を変数から取得できる」「変数を書き換えたら文字も書き換えることができる」という機能を付け加える必要があります。
たとえばチェックボックスのチェック状態も、なんらかの変数に代入しておいて、
- その変数を取得するだけでチェック状態がわかる
- その変数を書き換えるだけでチェック状態を変更できる
↑のようにしておく必要があります。
<script>
export default {
data:()=>({
isChecked: true, // isCheckedを取得するだけでチェック状態がわかる & isCheckedを書き換えるだけで、チェック状態の変更ができる必要がある
}),
}
</script>
※ dataの名前は自由につけてOKですが、今回は例としてisChecked
という名前にします。
このように、dataにひもづけて管理する必要があるということは、
つまりチェックボックスの表示内容は、常にdataの中のisChecked
に代入されている値と連動させる必要があるという事になります。
-
isChecked
がfalseだったら、チェックボックスの見た目はチェックが入ってない状態になっている必要がある -
isChecked
がtrueに変わったら、チェックボックスの見た目はチェックが入っている状態に変わっている必要がある
本来のHTMLでは勝手によろしくやってくれていた部分なのですが、
Vueではdataと紐付けて管理できるようにするために、
どのチェックボックスの状態を、どのdata(変数)で管理するのか を指定する必要があるのです。
そのためには、下記の2つの機能を追加する必要がある=2つのディレクティブを指定する必要がありました。
役割1. dataの内容を<input>
タグの表示内容と連動させる
ここからは、チェックボックスを具体例にして説明していきます。
まずは上の章で説明したように、<input>
タグの表示内容と、
そのチェックボックスの状態を管理しているdataを連動させる必要があります。
チェックボックスの表示内容は、checked属性という値で指定できます。
(これはVue独自の機能ではなく、ピュアなHTMLでも元々指定できる属性です)
<input type="checkbox" checked> <!-- checked属性を指定しておくと、チェックが入った状態で表示される -->
<input type="checkbox"> <!-- checked属性を指定しないでおくと、チェックが入ってない状態で表示される -->
そして、このchecked属性の内容を変数に連動させたいので
コードで書くと v-bind:checked="isChecked"
のように、
「checked属性の値はisCheckedという変数(コンポーネントのdata)の内容を自動的に読み取ってくださいね」と、
連動させておく必要があるのです。
(もともとのHTMLでは、chekced="false"
ような書き方はしないので、そこだけ少し独特な使い方かもしれません)
v-bind:
の書き方は:
と省略することができるので
:checked="isChecked"
でもOKです。
役割2. <input>
タグの表示内容が変わったらdataの中身も変更する
checked属性の内容がisCheckedと連動しているということは
チェックボックスの状態が変更されたら、
isCheckedの中身は、切り替わった後の値(true/false)を再代入しなければいけないということです。
つまり、チェック状態が切り替わったら処理をするという意味の v-on:change
というディレクティブで、
「isChecked
の中身を書き換える」という処理をする必要があるのです。
v-on:change="isChecked = 新しい値"
(ピュアなHTMLにも、状態が変わったときにJavaScriptの処理を実行するonchange
という属性がありましたが、v-on:change
はこれのVue版の書き方です)
(onchange属性をつかったことがない人は、一度ピュアなHTMLでonchange属性をつかって処理を実行してみると、イメージがつかみやすいと思います。)
新しい値は、changeイベントのターゲット(今回の場合チェックボックス)の値にすればいいので、
常に $event.target.value
でOKです。
v-on:change="isChecked = $event.target.value"
v-on:
の書き方は@
と省略することができるので
@change="isChecked = $event.target.value"
でもOKです。
この2つの処理がよく必要になるので、まとめて書けるようにした
チェックボックス以外にも、ユーザーから入力される
テキストエリアやセレクトボックスなどのHTMLタグも、
これと同じような処理は必ず必要になります。
(テキストエリアやセレクトボックスの場合、dataの中身はtrue/falseではなく文字列になりますが。)
この処理ができていないと
- 画面上の入力欄に入力をしたのに入力内容がdataに入ってない
- dataを書き換えたのに画面上の入力内容が変わらない
- 画面上の入力欄に入力をしたのに画面上の入力内容が変わらない=入力できない
など、
入力欄としてまともに使えない状態になります。
このように、入力欄として機能させるために必ず必要になる紐付けなのに、
毎回2つのディレクティブを指定しなければいけないのは非常に面倒です。
そのため、この2つの指定をまとめて指定できるようにしてくれたディレクティブが、v-model
です。
おわり
いかがでしょうか。
v-model
は便利機能というよりも最低限必要なもの、という認識が伝わったなら幸いです。
この記事の内容を理解したうえで、v-model
の書き方、使い方などを学んでいただけると
よりしっくり理解していただけるかな と思います。