v-model

v-modelの使い方-Vue.js

Vue.js Article

ここでは、v-modelディレクティブの基本的な使い方をサンプルコードを参考に解説していきます。

v-modelの基本的な使い方

v-modleformに関する要素(inputtextareaなど)にデータをバインドし、変更を監視するといった一連の動作を割り当てる(双方向バインディングを作成する)のに使われます。

Vue.js
v-model="変数"

v-onv-bindを用いても同じ動作を実現することができますが、複数ある場合には面倒で複雑になるのでこちらを利用することになると思います。

以下のコードではv-modelでdataのtextを双方向バインディングできるようにしています。

Vue.js
<div id="app">
  <input type="text" v-model="text" />
  <p>入力内容:{{text}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      text: "",
    },
  });
</script>

同じことをv-onv-bindを使って実装すると以下のようになります。

Vue.js
<div id="app">
  <input type="text" v-bind:value="text" v-on:input="changeText($event)" />
  <p>入力内容:{{text}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      text: "",
    },
    methods: {
      changeText(event) {
        this.text = event.target.value;
      },
    },
  });
</script>

v-onv-bindについてはこちら

v-modelの修飾子

v-modelにも修飾子があり、用いることでイベントのタイミングやデータに変更を加えることができます。

修飾子内容
lazyinputイベントの代わりにchnageイベントでデータを変更
number文字列から数値に型変換したのちにデータを変更
trim空白を取り除いたのちにデータを変更

lazy

デフォルトでは各inputイベント(※変換のあるものは変換決定後)でデータを変更しますが、lazyによってchangeイベントでデータを変更するようにできます。

type="text"だとEnterが押されたときやフォーカスが外れたとき(textareaはEnterで改行になる)、raidiocheckboxは要素が:checkedになったときなどです。changeイベントはHTMLElement: change イベントを参考に。

以下のコードでは入力後にEnterを押したり、フォーカスを外したりすると表示が変わります。

Vue.js
<div id="app">
  <input type="text" v-model.lazy="text" />
  <p>入力内容:{{text}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      text: "",
    },
  });
</script>

number

inputは常にvalueを文字列で返します。数値として扱いたい場合には、numberを付けることで自動的に型を変換してくれます。

以下のコードでは、num1では文字列として扱われ、表示されるのは入力の数字と1が横並び、num2では数値として扱われ、表示されるのは入力と1の計算結果となります。

Vue.js
<div id="app">
  <div>
    <input type="number" v-model="num1" />
    <p>num1:{{num1 + 1}}</p> <!-- 文字列として扱われ、文字列のつなぎ合わせとなる -->
  </div>
  <div>
    <input type="number" v-model.number="num2" />
    <p>num2:{{num2 + 1}}</p> <!-- 数値として扱われ、入力+1の結果となる -->
  </div>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      num1: null,
      num2: null,
    },
  });
</script>

trim

入力されたデータから空白を取り除いてくれます。

以下のコードでは、余分な空白を持つ入力から余分を取り除いてくれます。

Vue.js
<div id="app">
  <input type="text" v-model.trim="text" />
  <!-- Lorem     ipsum     dolor     sit     amet => Lorem ipsum dolor sit amet -->
  <p>{{text}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      text: "",
    },
  });
</script>

動的な値のバインディング

標準ではcheckboxは真偽値(Boolean)、radioselectは文字列と型が決まっています。しかし、決められた型以外をバインディングする方法も用意されています。

checkbox

checkboxの場合はチェックされているとき、されていないとき、それぞれにtrue-valuefalse-valueを用いて値をバインディングできます。

Vue.js
<div id="app">
  <input type="checkbox" v-model="toggle" true-value="true-value" false-value="false-value">
  <p>{{toggle}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      toggle: "",
    },
  });
</script>

注意する点は、

  • 初期の段階ではdataオプションで初期化された値が入る点
  • ブラウザはフォームの送信の中にチェックされていないチェックボックスを含めない点

です。

初期でtrue-valuefalse-valueのどちらかの値を表示したい場合には、dataオプションで初期化する必要があります。

また、このフォームを送信するときにチェックされていない場合はデータが含まれないので、どちらかの値が確実に送信されるためにはradioを使う必要があります

radio

radioにはv-bindを用いてバインディングすることができます。

以下のコードでは、初期で文字列を与えていますが、選択後にはnumber型の値が入ります。

Vue.js
<div id="app">
  <input type="radio" v-model="radio" v-bind:value="num">
  <p>{{num}}</p>
  <p>{{radio}}</p>
  <p>type: {{typeof radio}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      num: 11111,
      radio: "初期値"
    },
  });
</script>

select

selectにもv-bindでバインディングすることができます。

以下のコードでは、初期では文字列を与えていますが、選択肢を選ぶとそれぞれの値が入ります。

Vue.js
<div id="app">
  <select v-model="select">
    <option v-bind:value="num">{{num}}</option>
    <option v-bind:value="object">{{object.x}},{{object.y}}</option>
    <option v-bind:value="boolean">{{boolean}}</option>
  </select>
  <p>{{select}}</p>
  <p>type: {{typeof select}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      num: 11111,
      object: {x:10, y: 20},
      boolean: true,
      select: "初期値"
    },
  });
</script>

v-bindはこちら

複数選択

checkboxselectなどを複数選択にしたい場合があると思います。そのようなときには以下のような仕様となります。

checkbox

複数のinputタグに設定したv-modelが配列となります。

注意する点は初期段階で配列でない場合は有効ではない点です。

Vue.js
<div id="app">
  <input type="checkbox" v-model="check" value="apple" />
  <input type="checkbox" v-model="check" value="orange" />
  <input type="checkbox" v-model="check" value="peach" />
  <p>{{check}}</p>
  <p>type: {{typeof check}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      check: []
    },
  });
</script>

select

selectタグに設定したv-modelが配列となります。こちらは初期で配列でない場合でも大丈夫です。

Ctrlを押しながら複数選択することができます。

Vue.js
<div id="app">
  <select v-model="select" multiple>
    <option value="apple">apple</option>
    <option value="orange">orange</option>
    <option value="peach">peach</option>
  </select>
  <p>{{select}}</p>
  <p>type: {{typeof select}}</p>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      select: "初期値"
    },
  });
</script>

まとめ

今回はv-modelディレクティブの使い方についてまとめていきました。