Vue.js v-modelとフォーム部品


v-modelの修飾子

v-onと同様、v-modelにも修飾子を記述できる。

  • .lazy : 入力の完了時にバインドする。
  • .number : 数値型に変換
  • .trim : 前後のスペースを取り除く
.lazy

入力の完了時(Enterキーの押下やフォームからカーソルフォーカスが外れた時)にバインディングを行う。

<div id="app1">
  <div>
  <label for="bindData">入力中に同期:</label>
  <input name="bindData" type="text" v-model="bindData">
  </div>
  <div>
  <label for="lazy">入力完了時に同期:</label>
  <input name="lazy" type="text" v-model.lazy="bindData">
  </div>
  <p>{{bindData}}</p>
</div>
var app1 = new Vue({
  el: '#app1',
  data: {
    bindData: ""
  }
});
.number

数値型に変換する。文字列が入力された場合は変換しない。

<div>
<label for="number">変換しない:</label>
<input name="number" type="text" v-model="numberData">
</div>
<div>
<label for="number">数値型に変換:</label>
<input name="number" type="text" v-model.number="numberData">
</div>
<p>{{numberData + 2}}</p>
var app1 = new Vue({
  el: '#app1',
  data: {
    numberData: ""
  }
});

変換しない場合は、"入力文字列"の末尾に2が表示。変換時は加算処理が行われる。

複数の修飾子を組み合わせる

修飾子を繋げる記述で可能。

<input name="number" type="text" v-model.number.lazy="numberData">
radioボタンとv-model

name="group"の代わりにv-model="group"で関連するradioグループを括る。

<div id="app2">
  <h2>月に映画を見る回数は?</h2>
  <input v-model.number="movie" id="none" type="radio" value="0"><label for="none"> 全く観ない</label>
  <input v-model.number="movie" id="one" type="radio" value="1"><label for="one"> 1回</label>
  <input v-model.number="movie" id="under5" type="radio" value="2"><label for="under5"> 5回未満</label>
  <input v-model.number="movie" id="over5" type="radio" value="3"><label for="over5"> 5回以上</label>
  <p>{{comment}}</p>
</div>
var app2 = new Vue({
  el: '#app2',
  data: {
    movie: "",
  },
  computed: {
    comment: function(){
      var returnMsg = [
        "たまには気分転換に映画鑑賞などいかがですか?",
        "たまに観る映画楽しいですよね",
        "立派な映画好きです",
        "すごい!専門家になれるんでは!"
      ];
      return returnMsg[this.movie]
    }
  }
});
radioの初期デフォルトチェック

Vueのdataプロパティに初期値を入れることによって、デフォルトのチェックを入れることが出来る。この場合、value=0にチェックが入った状態になる。

var app2 = new Vue({
  el: '#app2',
  data: {
    movie: 0
  }
});
セレクトボックスとv-model
<select v-model.number="movie">
  <option value="0">全く観ない</option>
  <option value="1">1回</option>
  <option value="2">5回未満</option>
  <option value="3">5回以上</option>
</select>

jsは上記のradioのVueオブジェクトを使用。

チェックボックスとv-model

valueを指定しない場合、チェックonでtrue、チェックoffでfalseの値がバインディングされる。

<div id="app3">
<input v-model="global" id="global" type="checkbox"><label for="global"> 洋画</label>
</div>
var app3 = new Vue({
  el: '#app3',
  data: {
    // true or false
    global: false
  }
});

on / off時の値を設定するには、true-value="" false-value=""を指定すればよい。

<div id="app3">
  <h2>好きな映画のジャンルは?</h2>
  <input v-model="global" id="global" type="checkbox" true-value="洋画" false-value=""><label for="global"> 洋画</label>
  <input v-model="japanese" id="japanese" type="checkbox" true-value="邦画" false-value=""><label for="japanese"> 邦画</label>
  <input v-model="anime" id="anime" type="checkbox" true-value="アニメ" false-value=""><label for="anime"> アニメ</label>
  <p>{{global}}</p>
  <p>{{japanese}}</p>
  <p>{{anime}}</p>
</div>
var app3 = new Vue({
  el: '#app3',
  data: {
    global: "",
    japanese: "",
    anime:""
  }
});
checkboxの初期デフォルトチェック

プロパティにtrue-value時の値を初期化しておけばよい。

var app3 = new Vue({
  el: '#app3',
  data: {
    global: "",
    japanese: "邦画",
    anime:""
  }
});
グループ化されたチェックボックス

チェックボックスを配列化して取り扱う場合、v-modelに同名の要素を与えればよい。

この時、なぜかtrue-valueを指定すると制御不能となったので、value属性でチェック時の値の指定を行ったところ動作した。

<div id="app4">
  <h2>好きな映画の内容は?</h2>
  <input v-model="categories" id="global" type="checkbox" value="恋愛"><label for="global"> 恋愛</label>
  <input v-model="categories" id="japanese" type="checkbox" value="アクション"><label for="japanese"> アクション</label>
  <input v-model="categories" id="anime" type="checkbox" value="コメディ"><label for="anime"> コメディ</label>
  <p v-for="c in categories">{{c}}</p>
</div>
var app4 = new Vue({
  el: '#app4',
  data: {
    categories: []
  }
});
グループ化されたチェックボックスのデフォルトチェック

バインディング配列にチェックを入れたいindexに対して、初期化すればよい。

var app4 = new Vue({
  el: '#app4',
  data: {
    categories: ["", "アクション", ""]
  }
});
マルチプルとv-model

jsは上記のグループ化したチェックボックスのvueオブジェクトを使用。

<select v-model="categories" multiple>
  <option>恋愛</option>
  <option>アクション</option>
  <option>コメディ</option>
</select>
v-forとv-model

v-forを使用してグループ化されたradioボタンを表示。

var app5 = new Vue({
  el: '#app5',
  data: {
    radioDatas: [
      {value:"0", id:"i", text:"アイス"},
      {value:"1", id:"c", text:"チョコ"},
      {value:"2", id:"f",text:"果物"}
    ],
    //デフォルトチェッック
    loopValue: "1"
  }
});

html要素へのbindはv-bindを使用する。

<div id="app5">
<template v-for="data in radioDatas">
  <input type="radio" v-bind:id="data.id" v-bind:value="data.value" v-model="loopValue"><label v-bind:for="data.id">{{data.text}}</label>
</template>
<p>{{loopValue}}</p>
</div>

サンプルコード

Vue-Samples/v-model.html at master · letitride/Vue-Samples · GitHub