LoginSignup
98
74

More than 3 years have passed since last update.

【Vue】v-bindとv-onとv-modelの関係【基本】

Posted at

0. はじめに

本記事は、Vueのディレクティブであるv-bindv-onv-modelの役割と関係を整理することが目標です。
今回の説明で出てくるプログラムはVue CLIの<template>, <script>内に書くことを想定しています。

1. v-bindとv-onとv-modelの関係

1-1. v-bindについて

v-bindは htmlの属性をVueインスタンスのプロパティによって束縛する役割があります。
文章だとわかりにくいのでサンプルプログラムです。

template
<template>
  <div id="app">
    <input type="text" v-bind:value="myName">
  </div>
</template>
Vueインスタンス
export default {
  name: 'App',
  data() {
    return {
      myName: 'MouMou'
    }
  }
}

inputタグのvalue属性の前にv-bind:がついています。そのあとに="myName"がついています。
これはvalue属性の値を「VueインスタンスのdataプロパティのmyName」によって束縛します。という意味です。
dataプロパティのmyNameの値が変更するとv-bind:valueの値もmyNameに依存して変更されます。
ただし逆は成り立ちません。図にすると以下のようになります。
image.png
dataプロパティのmyNameの値を「太郎」にすると、テキストボックスの中身(= value)は「太郎」になりますが、
テキストボックスの中身(= value)を「太郎」にしても、dataプロパティのmyNameの値は「太郎」になりません。
v-bind:Vueインスタンス内のデータ→html属性 の単方向のみ

1-2.v-onについて

v-onはイベントのサブスクリプションを行います。
サブスクリプションとはイベントの起動を監視して、イベント発火時に指定したプログラムの実行を行う機能です。
サンプルプログラムは以下です。

template
<template>
  <div id="app">
    <input type="text" v-on:input="inputEvent">
  </div>
</template>
Vueインスタンス
export default {
  name: 'App',
  methods:{
    inputEvent(event) {
      console.log(event.target.value);
    }
  }
}

inputタグ内にv-on:input="inputEvent"があります。
これは、テキストボックスに文字がinputされたらinputEventメソッドを起動する。という意味です。
なお、inputEventメソッドに引数があります。こうすることでDOMイベントを渡すことが可能です。
(event.target.valueはテキストボックスに入った値を受け取ります。)
こちらも図にすると以下のようになります。
image.png
methodsプロパティからhtml属性にアクセスできませんが、
イベント(html属性)が発火することでmethodsプロパティのメソッドを実行することはできます。
v-on:html属性(イベント)→Vueインスタンス内のデータ の単方向のみ

1-3. v-modelについて

v-modelは双方向のデータバインディングを行います。
v-model=で定義された変数と、Vueインスタンスのデータプロパティの変数を紐づけ、
どちらかが変わるともう一方も変わる
挙動をします。

template
<template>
  <div id="app">
    <input type="text" v-model="myName">
    {{myName}}
  </div>
</template>
Vueインスタンス
export default {
  name: 'App',
  data() {
    return {
      myName: 'MouMou'
    }
  }
}

<input type="text">の場合、
v-modelvalue属性のバインディングとinputイベントのサブスクリプション両方の働きをしていることがわかります。
図にすると以下のようになります。
image.png

2. v-model = v-bind + v-on

v-modelv-bindv-on の組み合わせで実現できます。
言い換えると、v-modelは「v-bindv-onの組み合わせの省略記法」とも言えますね。
1-3のv-modelサンプルをv-bindv-onの組み合わせで実現すると以下になります。

template
<template>
  <div id="app">
    <input type="text" v-bind:value="myName" v-on:input="changeMyName">
    {{myName}}
  </div>
</template>
Vueインスタンス
export default {
  name: 'App',
  data() {
    return {
      myName: 'MouMou'
    }
  },
  methods:{
    changeMyName(event) {
      this.myName = event.target.value;
    }
  }
}

image.png

1-3のv-modelのサンプルと比べて冗長でわかりにくいですが、同じ挙動をします。
v-modelを使用することで、双方向のバインディングがすっきりかけて、わかりやすくなりますね。

なお、Vue公式サイトには以下のような記載があります

内部的には、v-modelは異なる input 要素に対し異なるプロパティを使用し、異なるイベントを送出します。

text および textarea 要素には、valueプロパティとinputイベントを用います
チェックボックスおよびラジオボタンには、checkedプロパティとchangeイベントを用います
select フィールドには、valueプロパティとchangeイベントを用います

3. まとめ

  • v-modelv-bindv-onで実現できる

最後まで読んでいただきありがとうございました!

参考

98
74
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
98
74