0. はじめに
本記事は、Vueのディレクティブであるv-bind
とv-on
とv-model
の役割と関係を整理することが目標です。
今回の説明で出てくるプログラムはVue CLIの<template>
, <script>
内に書くことを想定しています。
1. v-bindとv-onとv-modelの関係
1-1. v-bind
について
v-bind
は htmlの属性をVueインスタンスのプロパティによって束縛する役割があります。
文章だとわかりにくいのでサンプルプログラムです。
<template>
<div id="app">
<input type="text" v-bind:value="myName">
</div>
</template>
export default {
name: 'App',
data() {
return {
myName: 'MouMou'
}
}
}
inputタグのvalue属性の前にv-bind:
がついています。そのあとに="myName"
がついています。
これはvalue属性の値を「VueインスタンスのdataプロパティのmyName
」によって束縛します。という意味です。
dataプロパティのmyName
の値が変更するとv-bind:value
の値もmyName
に依存して変更されます。
ただし逆は成り立ちません。図にすると以下のようになります。
dataプロパティのmyName
の値を「太郎」にすると、テキストボックスの中身(= value)は「太郎」になりますが、
テキストボックスの中身(= value)を「太郎」にしても、dataプロパティのmyName
の値は「太郎」になりません。
v-bind
:Vueインスタンス内のデータ→html属性 の単方向のみ
1-2.v-on
について
v-onは
イベントのサブスクリプションを行います。
サブスクリプションとはイベントの起動を監視して、イベント発火時に指定したプログラムの実行を行う機能です。
サンプルプログラムは以下です。
<template>
<div id="app">
<input type="text" v-on:input="inputEvent">
</div>
</template>
export default {
name: 'App',
methods:{
inputEvent(event) {
console.log(event.target.value);
}
}
}
inputタグ内にv-on:input="inputEvent"
があります。
これは、テキストボックスに文字がinputされたらinputEventメソッドを起動する。という意味です。
なお、inputEventメソッドに引数があります。こうすることでDOMイベントを渡すことが可能です。
(event.target.value
はテキストボックスに入った値を受け取ります。)
こちらも図にすると以下のようになります。
methodsプロパティからhtml属性にアクセスできませんが、
イベント(html属性)が発火することでmethodsプロパティのメソッドを実行することはできます。
v-on
:html属性(イベント)→Vueインスタンス内のデータ の単方向のみ
1-3. v-model
について
v-model
は双方向のデータバインディングを行います。
v-model=
で定義された変数と、Vueインスタンスのデータプロパティの変数を紐づけ、
どちらかが変わるともう一方も変わる挙動をします。
<template>
<div id="app">
<input type="text" v-model="myName">
{{myName}}
</div>
</template>
export default {
name: 'App',
data() {
return {
myName: 'MouMou'
}
}
}
<input type="text">
の場合、
v-model
はvalue
属性のバインディングとinput
イベントのサブスクリプション両方の働きをしていることがわかります。
図にすると以下のようになります。
2. v-model
= v-bind
+ v-on
v-model
は v-bind
と v-on
の組み合わせで実現できます。
言い換えると、v-model
は「v-bind
とv-on
の組み合わせの省略記法」とも言えますね。
1-3のv-model
サンプルをv-bind
とv-on
の組み合わせで実現すると以下になります。
<template>
<div id="app">
<input type="text" v-bind:value="myName" v-on:input="changeMyName">
{{myName}}
</div>
</template>
export default {
name: 'App',
data() {
return {
myName: 'MouMou'
}
},
methods:{
changeMyName(event) {
this.myName = event.target.value;
}
}
}
1-3のv-model
のサンプルと比べて冗長でわかりにくいですが、同じ挙動をします。
v-model
を使用することで、双方向のバインディングがすっきりかけて、わかりやすくなりますね。
なお、Vue公式サイトには以下のような記載があります
内部的には、v-modelは異なる input 要素に対し異なるプロパティを使用し、異なるイベントを送出します。
text および textarea 要素には、valueプロパティとinputイベントを用います
チェックボックスおよびラジオボタンには、checkedプロパティとchangeイベントを用います
select フィールドには、valueプロパティとchangeイベントを用います
3. まとめ
-
v-model
はv-bind
とv-on
で実現できる
最後まで読んでいただきありがとうございました!