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>