【Vue.js】v-modelでフォーム要素をコントロールする

スポンサーリンク

v-modelの使い方

v-から始まるディレクティブについて書いた記事はこちら↓

改めて、inputタグとv-modelでデータバインディングをする方法を記載。

<input type="text" v-model="textData.str" />
<p>{{textData.str}}</p>

<script>
export default {
  data() {
    return {
      textData:{
        str:"text"
      }
    };
  }
};
</script>

lazy修飾子

v-modelに.lazy修飾子をつけることによって、inputの文字列入力からフォーカスが外れた時に値の更新が行われるようになる。
(changeイベントで発火)
.lazyをつけていない時は、リアルタイムに値が反映する。

<input type="text" v-model.lazy="textData.str" />

.lazy修飾子は、v-modelにドット(.)で繋げて記載する。

number修飾子

input type=”number”は値を更新するとString型になってしまう。
number型に固定するために、.number修飾子を用いる。

<input id="userNumber" type="number" v-model.number="textData.userNumber"/>

trim修飾子

先頭と後ろの空白を削除する働きをする。
文字列中(間)の空白は削除しない。

<input id="userName" type="text" v-model.trim="textData.userName"/>

textareaと双方向データバインディングを作る

textareaでの複数行テキストにv-modelを使ってデータバインディングすることができる。
改行や空白を表示したいときは、preタグかpタグの中に、

<p style="white-space: pre;">{{ }}</p>

とすると改行&空白を表示することができる。
JavaのTymeleafテンプレートの時もpreタグをずっと使っていたので、pタグに追記するよりもpreを愛用しています。

textareaとデータバインディングするコードはこちら。

<textarea id="detail" cols="30" rows="10" v-model="textData.detail"></textarea>
<pre>{{textData.detail}}</pre>

【単体】checkboxと双方向データバインディングを作る

checkboxの単体と複数ではv-modelの書き方が異なる。
単体checkboxにv-modelを使う時は、boolean型になる。

<input type="checkbox" id="agree" v-model="textData.agree">
<label for="agree">同意する</label>
<p>{{textData.agree}}</p>

// 省略
 data() {
    return {
        agree:false
      }
    };
  },
// 省略

【複数】checkboxと双方向データバインディングを作る

複数のcheckboxにv-modelを使う場合、配列になる。
ひとまとめのグループ内にinput type=”checkbox”にはv-modelを同じ値にする。

<input type="checkbox" id="spring" value="春" v-model="textData.likeSeasons" />
<label for="spring">春</label>

<input type="checkbox" id="summer" value="夏" v-model="textData.likeSeasons" />
<label for="summer">夏</label>

<input type="checkbox" id="autumn" value="秋" v-model="textData.likeSeasons" />
<label for="autumn">秋</label>

<input type="checkbox" id="winter" value="冬" v-model="textData.likeSeasons" />
<label for="winter">冬</label>

<p>{{textData.likeSeasons}}</p>

// 省略
data() {
    return {
        likeSeasons:[]
      }
    };
  },
// 省略

radiobutton と双方向データバインディングを作る

複数checkboxと同じように、ひとまとめのグループに同じ値のv-modelを適用する事で、vueが「これは同じグループのラジオボタンですね」と認識する。
ラジオボタンは選択が一つしかできないので、保持される値は、単一のデータになる。(配列ではない)

<input type="radio" id="male" value="男性" v-model="textData.gender">
<label for="male">男性</label>

<input type="radio" id="female" value="女性" v-model="textData.gender">
<label for="female">女性</label>

<p>{{textData.gender}}</p>

// 省略
data() {
    return {
        gender:"男性"
      }
  };
},
// 省略

selectboxと双方向データバインディングを作る

まず、v-modelの話の前に、selectboxの中のoptionはv-forを使ってリスト表示を簡単に記載する事ができる。

<select>
  <option v-for="location in locations" :key="location">{{location}}</option>
</select>

// 省略
 data() {
    return {
      locations:["日本","アメリカ","中国"],
    };
  },
// 省略

v-modelでデータバインディングする時は、selectタグの中にv-modelを記載する。

<select v-model="textData.location">
   <option v-for="location in locations" :key="location">{{location}}</option>
</select>
<p>{{textData.location}}</p>

// 省略
  data() {
    return {
      locations:["日本","アメリカ","中国"],
      textData: {
        location:"アメリカ"
      }
    };
  },
// 省略

selectboxを複数選択させたい時は、selectタグに multiple を追加する。

<select v-model="textData.location" multiple>

複数選択する場合は、配列になるので、dataも配列で受け取るように設定する。

  data() {
    return {
      locations:["日本","アメリカ","中国"],
      textData: {
        location:[]
      }
    };
  },

v-modelは別の形で書く事ができる

v-modelを使わなくても、下記のように書く事ができる。

<input id="str" type="text" :value="textData.str" @input="textData.str = $event.target.value" />

lazyにするときは、@inputを@changeにすると実装できる。

<input id="str" type="text" :value="textData.str" @change="textData.str = $event.target.value" />

上記は、input type=”text”での書き方になるので、checkboxやradioの時は変わってくる。

コンポーネントにv-modelを使用する

子コンポーネントを作る際に、値の受け渡しができるように上記の別の書き方で記載をしていく。

データを渡していくので、propsを指定する。

<script>
export default {
    props:["value"]
};
</script>

propsについての記事はこちら↓

inputタグのvalue値にpropsで指定した値を入れ込む。

<input id="str" type="text" :value="value">

@inputイベントを発火させるためのコードを記載していく。
イベント発火には$emitを使用する。
inputに入力があったら、親コンポーネントのinputイベントを発火させる。

$emitの第2引数には、渡したい値を入れる。inputで入力した値を与えたいので、eventを使用する。

<input id="str" type="text" :value="value" @input="$emit('input',$event.target.value)" />

$emitについての記事は、こちら。見出し「子から親へデータを受け渡す」を参照↓

親コンポーネント上では、子コンポーネントをimportし、コンポーネント登録を行う。

<script>
import User from "./components/User.vue";

export default {
 data() {
    return {
      textData: {
        str: "title",
      }
    };
  },
 components: {
    User
  }
};
</script>

子コンポーネント名のタグ内にv-modelを設定。

<User v-model="textData.str"></User>
タイトルとURLをコピーしました