本記事では、Vue.jsのv-modelディレクティブについて紹介します。
目次
v-modelディレクティブ
ユーザーからの入力を受け取るWebアプリケーションでは、テキストボックスやチェックボックスなどの入力要素をフォーム(form)に配置します。
Webアプリケーションは、フォームに配置した要素に入力された値を取得して、JavaScriptなどのプログラム(Vuenのインスタンス内)で処理を行います。
また、データベースやファイルなどから取得したデータをプログラムからフォームの要素に設定します。
Vue.jsでは、フォームに配置された要素とプログラムが、お互いに(双方向に)データをやり取りする際に、v-modelディレクティブを使用します。
v-modelディレクティブを使用して値をバインドできる要素には
- input[type=text]
- input[type=checkbox]
- input[type=radio]
- input[type=number]
- input[type=date]
- input[type=time]
- input[type=tel]
- input[type=url]
- input[type=color]
- input[type=range]
- textarea
- select
などがあります。
v-modelディレクティブは、value属性を持ち、input, changeイベントを持つ要素で使用することができます。
v-modelディレクティブでデータをバインドした(紐づけた)フォームの要素の値を変更すると、inputイベントのタイミングでVueのインスタンスに定義したデータの値が変更されます。
v-modelディレクティブの書式
v-modelディレクティブはHTML要素の属性と同じように指定し、引数にデータを指定します。
1 |
<要素名 v-model="バインドするデータ(プロパティ)名" /> |
要素名には「input」などのフォーム入力要素を指定し、データ名にはVueインスタンスのdataオプションに定義したデータを指定します。
v-modelディレクティブの使用例
ここではv-modelディレクティブを使用して、フォームの要素とデータをバインドする例をいくつか示します。
テキストボックス input[type=text]
input[type=text](改行できない(1行の)入力欄)にVueインスタンスのデータをバインドすると以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!-- HTML --> <div id="app"> <input type="text" v-model="value" /> <p> {{value}} </p> </div> <!-- JavaScript (Vue.js) --> <script> Vue.createApp({ data: function() { return { value: '', } } }).mount('#app') </script> |
テキストボックスには文字列をバインドします。
複数行テキストボックス textarea
textarea(改行できる入力欄)にVueインスタンスのデータをバインドすると以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!-- HTML --> <div id="app"> <textarea v-model="value"></textarea> <p> {{value}} </p> </div> <!-- JavaScript (Vue.js) --> <script> Vue.createApp({ data: function() { return { value: '', } } }).mount('#app') </script> |
チェックボックス input[type=checkbox]
input[type=checkbox](1つのチェックボックス)にVueインスタンスのデータをバインドすると以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!-- HTML --> <div id="app"> <input type="checkbox" v-model="value" /> <p> {{value}} </p> </div> <!-- JavaScript (Vue.js) --> <script> Vue.createApp({ data: function() { return { value: false, } } }).mount('#app') </script> |
チェックボックスには真偽値(ture/false)をバインドします。
複数のチェックボックス
複数のチェックボックスにVueインスタンスのデータをバインドすると以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!-- HTML --> <div id="app"> <input type="checkbox" v-model="values" value="option1" /> <input type="checkbox" v-model="values" value="option2" /> <input type="checkbox" v-model="values" value="option3" /> <p> {{values}} </p> </div> <!-- JavaScript (Vue.js) --> <script> Vue.createApp({ data: function() { return { values: [], } } }).mount('#app') </script> |
複数のチェックボックスには配列をバインドします。
チェックを付けたもの(チェックがオンのチェックボックスのvalue属性の値)だけが、配列に代入されます。
ラジオボタン input[type=radio]
input[type=radio](複数の選択肢から1を選ぶオプション)にVueインスタンスのデータをバインドすると以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!-- HTML --> <div id="app"> <input type="radio" v-model="value" value="option1" /> <input type="radio" v-model="value" value="option2" /> <input type="radio" v-model="value" value="option3" /> <p> {{value}} </p> </div> <!-- JavaScript (Vue.js) --> <script> Vue.createApp({ data: function() { return { value: '', } } }).mount('#app') </script> |
ラジオボタンには文字列をバインドします。
ラジオボタンにバインドする値には、要素のvalue属性の値が代入されます。
セレクトボックス(ドロップダウンリスト形式の選択肢)select
select(プルダウン方式で項目を1つ選択するボックス)にVueインスタンスのデータをバインドすると以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<!-- HTML --> <div id="app"> <select v-model="value"> <option value="option1">選択肢1</option> <option value="option2">選択肢2</option> <option value="option3">選択肢3</option> </select> <p> {{value}} </p> </div> <!-- JavaScript (Vue.js) --> <script> Vue.createApp({ data: function() { return { value: '', } } }).mount('#app') </script> |
セレクトボックスには文字列をバインドします。
セレクトボックスにバインドする値には、要素が持つリストの中で選択されているオプション(option)のvalue属性の値が代入されます。
複数選択リストボックス
一覧形式で複数の項目を選択できるリストボックスにVueインスタンスのデータをバインドすると以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<!-- HTML --> <div id="app"> <select v-model="values" multiple> <option value="option1">選択肢1</option> <option value="option2">選択肢2</option> <option value="option3">選択肢3</option> </select> <p> {{values}} </p> </div> <!-- JavaScript (Vue.js) --> <script> Vue.createApp({ data: function() { return { values: [], } } }).mount('#app') </script> |
複数選択できるリストボックスには配列をバインドします。
v-modelディレクティブの修飾子
v-modelディレクティブで使用する修飾子は、フォーム入力バインディングをサポート(動作を変更、または付加)します。
v-modelディレクティブの修飾子には、以下の3つがあります。
- .lazy
- .number
- .trim
修飾子は「v-model」の後に「.」(ドット)で続けて「v.model.lazy」のように記述します。
例えば「v-model=”value”」に修飾子の.lazyを付けると「v-model.lazy=”value”」となります。
.lazy修飾子
.lazy修飾子を指定してバインドしたフォームの要素は、changeイベントが発生したタイミングでデータバインド(データの変更)が行われます。(.lazy修飾子を指定していない場合はinputイベントのタイミングでデータバインドが行われます。)
IMEの全角入力モードが有効(オン)になっている状態であれば、入力が確定したタイミングではなく、要素からフォーカスが移動したタイミング(要素がフォーカスを失ったタイミング)でデータが更新されます。
.number修飾子
.number修飾子を指定してバインドしたフォームの要素では、データが数値として扱われます。(バインドしているデータに数値型の値が代入されます。)
フォームのinput要素では、value属性の値が文字列型として扱われますが、.number修飾子を指定することによって、明示的に数値型にすることができます。
数値のみ(数値とみなされない文字列は除外した)の値としてバインドしたい場合(ユーザーの誤入力を防ぎたい場合など)に使用できます。
.trim修飾子
.trim修飾子を指定してバインドしたフォームの要素(テキストボックス)では、入力された文字列の前後に空白文字列(半角スペース、タブ文字、改行など)がある場合に、自動的に除去されます。バインドしているデータの値がトリミングされますので、フォームの要素の値もトリミングされます。(データバインド が行われた際に要素のvalue属性の値も変換されます。)
前後に空白を許可したくない場合(ユーザーの誤入力を防ぎたい場合など)に使用できます。
フォームの入力要素のv-modelディレクティブ確認用コード
主なフォームの入力要素とVueインスタンスのdataオプションで定義したデータをバインドしたコードを以下に記載します。
このコードをhtmlファイルに貼り付けて実行すると、v-modelで双方向バインディングした時の動作の結果を確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
<script src="https://unpkg.com/vue@next"></script> <div id="app"> <input type="text" v-model="text" /> <p> {{text}} </p> <input type="text" v-model.lazy="lazy" /> <p> {{lazy}} </p> <input type="text" v-model.trim="trim" /> <p> {{trim}} </p> <input type="checkbox" v-model="checkbox" value="check" /> <p> {{checkbox}} </p> <input type="checkbox" v-model="check" value="item1" /> <input type="checkbox" v-model="check" value="item2" /> <input type="checkbox" v-model="check" value="item3" /> <p> {{check}} </p> <input type="radio" v-model="radio" value="item1" /> <input type="radio" v-model="radio" value="item2" /> <input type="radio" v-model="radio" value="item3" /> <p> {{radio}} </p> <input type="number" v-model.number="number" /> <p> {{number}} </p> <input type="date" v-model="date" /> <p> {{date}} </p> <input type="time" v-model="time" /> <p> {{time}} </p> <input type="tel" v-model="tel" /> <p> {{tel}} </p> <input type="url" v-model="url" /> <p> {{url}} </p> <input type="color" v-model="color" /> <p> {{color}} </p> <input type="range" v-model.number="range" /> <p> {{range}} </p> <textarea v-model="textarea"></textarea> <p> {{textarea}} </p> <select v-model="select"> <option value="item1">アイテム1</option> <option value="item2">アイテム2</option> <option value="item3">アイテム3</option> </select> <p> {{select}} </p> <select v-model="multi" multiple> <option value="item1">アイテム1</option> <option value="item2">アイテム2</option> <option value="item3">アイテム3</option> </select> <p> {{multi}} </p> </div> <script> Vue.createApp({ data: function() { return { text: '', lazy: '', trim: '', checkbox: false, check: [], radio: '', number: 0, date: '', time: '', tel: '', url: '', color: '', range: 0, textarea: '', select: '', multi: [] } } }).mount('#app') </script> |
上記のコードを実行してHTMLの入力要素の値を変更すると、v-modelディレクティブでバインドしたデータが動的に変化するのが確認できます。