vue.jsを使ってアプリケーションを構築する際に入力フォームを使う場合はvue.jsを使って入力フォームの要素を制御する必要があります。要素によって設定方法が異なるので、使いこなせるようにしっかりと理解しておきましょう。

v-modelディレクティブ

入力フォームとvue.jsの管理下にあるデータを結びつけるためにv-modelディレクティブを利用します。v-modelを利用すればinput要素、textarea要素、select要素に入力した値をvue.jsのデータとして扱うことができます。一つ一つの要素での使用方法を確認しながら理解を進めていきます。

vue.jsではv-を接頭語にしたディレクティブという特別な属性が多数存在します。vue.jsはそのディレクティブを識別してどのような動作を行うか判断します。入力フォームの値とvue.jsのデータを結びつける場合はv-modelを利用します。

テキストボックスの場合

テキストボックスでv-modelディレクティブを使用する場合は下記のように記述します。


<input type="text" v-model="プロパティ名">

実際にテキストボックスを使って動作確認を行います。プロパティ名をtextInputとしてinput要素をhtml文の中に追加します。


<div id="app">
    <input type="text" v-model="textInput">
</div>

vue.jsのdataの中にtextInputプロパティを追加し、初期値は”(ブランク)とします。


var app = new Vue({
  el: '#app',
  data: {
  	textInput: '',		
  }
})	

画面上には、input要素によるテキストボックスの入力エリアが表示されます。この状態ではテキストボックスに何か文字列を入力してもテキストボックスに入力した文字が表示されるだけでそれ以外は何も変化がありません。

input テキスト入力フォーム
input テキスト入力フォーム

次に入力した内容を見るためにはvue.jsのdataであるtextInputプロパティを画面に表示させます。{{ textInput }}を使ってhtmlの中に埋め込みます。


<div id="app">
    <input type="text" v-model="textInput">
    <p>{{ textInput }}</p>
</div>

テキストボックスに文字列を打ち込むと入力した内容がそのままテキストボックスの下に表示されます。このようにv-modelを使用することで入力したデータが即座にvue.jsのdataのtextInputに反映され、そのデータがブラウザ上に表示されることがわかります。

inputフォームの下に表示
inputフォームの下に表示

通常のテキストボックスの場合はvalue属性に値(<input text=”type” value=”初期値”>)を設定するとその値がテキストボックスに入った状態で表示されます。しかし、v-modelではvalue値を事前に入力してもvalueに設定した値はブラウザには表示されません。

初期値を入れるためには、属性値のvalueではなくdataのtextInputの値を設定しておく必要があります。


var app = new Vue({
  el: '#app',
  data: {
  	textInput: '初期値はここに入れておく',		
  }
})	

ブラウザで確認すると初期値が入力された状態で表示されます。

初期値を入力
初期値を入力

双方向バインディングとは

テキストボックスのv-modelの使い方が理解できたと思いますので、用語の確認を行なっておきます。

v-modelの説明を調べていくと双方向バインディングやTwo wayバインディングという用語をよく目にします。それらがどういう意味なのか確認していきましょ。

バインディングやバインド?

バインディング(binding)とバインド(bind)は英語ではどちらも同じ意味で何かと何かを結びつけることを意味します。

vue.jsではVueインスタンスの中でdataプロパティを設定し、htmlの要素(下記ではp要素)にv-textを設定することでdataプロパティの値をhtmlの要素の中に表示させることができます。このようにdataプロパティと要素が結びついているのでバインドまたはバインディングといいます。


<div id="app">
	<p v-text="textInput"></p>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
  el: '#app',
  data: {
  	textInput: 'バインディングとは',		
  }
})

双方向(two way)バインディング

双方向(Two Way)ということは2つ方向のバインディングがあることを表しています。

v-textでは1方向のバインドでしたが、v-modelになると双方向のバインドになります。

一つ目の方向は、Vueインスタンスの中で設定したdataプロパティの値がinput要素と結びついてブラウザ上に表示されるもので、もう一つの方向はinput要素に入力した値がVueインスンスのdataプロパティの値に反映されるバインドです。このように2つの方向を持っているので双方向(two way)バインディングと呼ばれます。

双方向バインディング
双方向バインディング

テキストエリアの場合

テキストボックスでは改行を行うことができないので長い文章は入力することができません。改行が可能な長い文章を入力する場合はテキストエリアtextarea要素を使用します。テキストエリアでv-modelディレクティブを使用する場合は下記のように記述します。


<textarea v-model="プロパティ名"></textarea>

テキストエリアなので値はtextareaタグの中に入れてしまいそうですが、下記のように記述しても双方向ではないので中身を更新してもvue.jsのdataプロパティには値の反映は行われません。


<textarea>{{ textInput }}</textarea>

チェックボックスの場合

1つのチェックボックスの場合

v-modelを使用したチェックボックスの書式は下記となります。


<input type="checkbox" v-model="プロパティ名">

checkboxのプロパティはtrue, falseの真偽値のみ設定することが可能です。

チェックボックスを準備してプロパティはcheckValueとします。現在の設定値がわかるように{{ checkValue }}を使って値も表示させます。


<div id="app">
	<input type="checkbox" v-model="checkValue">
	<p>{{ checkValue }}</p>
</div>

チェックボックスではプロパティは真偽値をとるので、初期値はtrueとします。


<script>
var app = new Vue({
  el: '#app',
  data: {
  	checkValue: true,		
  }
})
</script>

ブラウザで確認すると下記のように表示されます。初期値がtrueなので、ボックスが選択された形で表示されます。

チェックボックスの値をtrue
チェックボックスの値をtrue

チェックを外すと値はtrueからfalseに変わります。

チェックを外した場合
チェックを外した場合

true、falseしかとれないと説明しましたが、true-value、false-valueという属性を利用するとtrue, false以外の値をとることができます。

下記ではtrue-valueとfalse-valueを使用して”はい”と”いいえ”になるように変更を行なっています。


<div id="app">
	<input type="checkbox" v-model="checkValue" true-value="はい" false-value="いいえ">
	<p>{{ checkValue }}</p>
</div>

checkValueプロパティの初期値は”はい”とします。


<script>
var app = new Vue({
  el: '#app',
  data: {
  	checkValue: 'はい',		
  }
})
</script>

初期値が”はい”になっているので、チェックした状態で値は”はい”となります。

checkboxをチェックした状態
checkboxをチェックした状態

チェックを外すと”いいえ”となります。

checkboxを外した場合
checkboxを外した場合

このようにtrue-value, false-valueを設定することでtrue, falseの真偽値から任意の値を取れるようになることが確認できました。

複数のチェックボックスの場合

複数のチェックボックスを利用する場合の書式は下記の通りです。


<input type="checkbox" v-model="プロパティ名" value="値1">
<input type="checkbox" v-model="プロパティ名" value="値2">
<input type="checkbox" v-model="プロパティ名" value="値3">

1つのチェックボックスではデフォルトでは真偽値のtrue, falseの2つをとることができますが、複数のチェックボックスの場合は、各チェックボックで設定したvalueの値を配列で取得します。

実際に確認してみましょう。

同じグループの場合は、v-modelには同じプロパティを設定し、valueにはそのチェックボックスが選択された時の値を設定します。checkValueプロパティの値をブラウザに表示できるように{{ checkValue }}も追加します。


<div id="app">
	<input type="checkbox" v-model="checkValue" value="ラグビー"> ラグビー
	<input type="checkbox" v-model="checkValue" value="サッカー"> サッカー
	<input type="checkbox" v-model="checkValue" value="バスケットボール"> バスケットボール
	<p>{{ checkValue }}</p>
</div>

checkValueは配列なので、初期値は空の配列を設定します。


<script>
var app = new Vue({
  el: '#app',
  data: {
  	checkValue: [],		
  }
})

デフォルトは何も選択していない状態なので、下記のようになります。

何も選択していない状態
何も選択していない状態

サッカーのみを選択すると配列にサッカーが入ることがわかります。

サッカーのみ選択
サッカーのみ選択

サッカーの次にバスケットボール、ラグビーと選択すると選択した順に値は配列に入っていくことがわかります。

すべてをチェックした状態
すべてをチェックした状態

このように複数のチェックボックスでは各チェックボックスに設定した値が配列としてvue.jsのdataプロパティの中に保存されることがわかります。

初期値を設定しておきたい時は下記のようにcheckValueの配列に値を入れておきます。


<script>
var app = new Vue({
  el: '#app',
  data: {
  	checkValue: ['サッカー'],		
  }
})

チェックボックスに選択肢にないものを入れることも可能ですが、チェックボックスの選択からの影響は受けず配列に入ったままの状態となります。


<script>
var app = new Vue({
  el: '#app',
  data: {
  	checkValue: ['サッカー','野球'],		
  }
})

チェックボックスに選択する値がなくても野球は配列には入った状態になります。

チェックボックスに影響を受けない値
チェックボックスに影響を受けない値

すべてのチェックボックスを外しても配列に残った状態となり、チェックボックスからの影響は全く受けません。

チェックボックスに影響を受けない
チェックボックスに影響を受けない

ラジオボタンの場合

ラジオボタンでは複数の選択肢から1つを選択させたい場合に利用します。複数のチェックボックスと設定方法はほとんど同じですが、ラジオボタンでは値は配列ではなく文字列として取得します。

ラジオボタンの書式は下記の通りです。


<input type="radio" v-model="プロパティ名" value="値1">
<input type="radio" v-model="プロパティ名" value="値2">
<input type="radio" v-model="プロパティ名" value="値3">

実際にラジオボタンを使って動作確認を行なってみましょう。

同じグループの場合は、v-modelには同じプロパティを設定し、valueにはそのラジオボタンが選択された時の値を設定します。radioValueプロパティの値をブラウザに表示できるように{{ radioValue }}も追加します。


<div id="app">
	<input type="radio" v-model="radioValue" value="ラグビー"> ラグビー
	<input type="radio" v-model="radioValue" value="サッカー"> サッカー
	<input type="radio" v-model="radioValue" value="バスケットボール"> バスケットボール
	<p>{{ radioValue }}</p>
</div>

radioValueは文字列なので、初期値は”(ブランク)を設定します。


<script>
var app = new Vue({
  el: '#app',
  data: {
  	radioValue: ''	
  }
})
</script>	

ラジオボタンを選択していない状態です。

ラジオボタンを選択していない状態
ラジオボタンを選択していない状態

ラジオボタンを選択すると選択した値が{{ radioValue}}に表示されます。

ラジオボタンを選択した状態
ラジオボタンを選択した状態

ラジオボタンは複数の選択を行うことができないので、別のボタンに変更すると別の選択した値がブラウザ上に表示されます。

セレクトボックスの場合

1つを選択する場合

プルダウンメニューを使って選択肢の中から1つだけ選択する場合のセレクトボックスの設定方法を確認します。1つだけ選択を行うので値は文字列として取得できます。

セレクトボックスの書式は下記の通りです。


<select v-model="selectValue">
	<option>値1</option>
	<option>値2</option>
	<option>値3</option>
</select>
<p>{{ selectValue }}</p>

実際にセレクトボックスを使って動作確認を行なってみましょう。

select要素にv-modelでselectValueプロパティを設定します。プルダウンメニューで選択した値はこのselectValueプロパティの値に入ります。selectValueの値は{{ selectValue }}でブラウザに表示されます。

optionにdisabledが設定されていますが、disabledを選択した項目は選択することができません。ページを開いた直後はこの選択項目が表示されていますが、一度選択を開始するとdisabledの項目を選択できなくなります。

<div id="app">
	<select v-model="selectValue">
		<option disabled value="">興味のあるスポーツを選択</option>
		<option>ラグビー</option>
		<option>サッカー</option>
		<option>バスケットボール</option>
	</select>
	<p>{{ selectValue }}</p>
</div>

selectValueプロパティの値は文字列なので””(ブランク)を設定しています。


<script>
var app = new Vue({
  el: '#app',
  data: {
  	selectValue: ''	
  }
})
</script>	

ページを開いた直後は、disabledの項目が表示されています。

プルダウンメニューで何も選択されていない状態
プルダウンメニューで何も選択されていない状態

プルダウンメニューで選択すると下記のように選択した値がブラウザに表示されます。

プルダウンメニューで選択
プルダウンメニューで選択

プルダウンメニューを選択している状態です。disabledに設定した項目は選択することができません。

プルダウンメニューを選択している状態
プルダウンメニューを選択している状態

selectValueにデフォルト値を選択するとプルダウンメニューで選択された状態で表示されます。

複数を選択する場合

一つの選択の場合は、文字列で値を取得できましたが、複数の場合は配列で値を取得することができます。

複数を選択可能にするためには、select要素にmultipleを設定する必要があります。html部分の記述に関しては1つを選択する場合と複数を選択する場合の違いはmultipleを追加するかどうかの違いです。


<div id="app">
	<select v-model="selectValue" multiple="">
		<option>ラグビー</option>
		<option>サッカー</option>
		<option>バスケットボール</option>
	</select>
	<p>{{ selectValues }}</p>
</div>

値を複数選択することができるので、select_valuesプロパティの初期値は配列を設定します。


<script>
var app = new Vue({
  el: '#app',
  data: {
  	selectValues: []
  }
})

selectにmultipleを設定するとプルダウンメニューではなく複数の要素を選択する画面になります。

select要素による複数選択画面
select要素による複数選択画面

複数選択を行うと選択した値が配列で表示されます。

複数要素を選択した画面
複数要素を選択した画面

ファイルの場合

HTMLの入力フォームではinput要素のtypeをfileに設定することでファイル情報を取得することができます。しかし、v-modelではファイルタイプを扱うことはできません。その代わり、changeイベントを利用してファイル情報を取得することができます。

これまではv-modelを使用していましたがファイルの場合はchangeイベントを利用します。changeイベントを設定しているので、ファイルの選択が行われれるとchangeイベントに設定されているhandleFileメソッドが実行されます。

changeイベントはv-onディレクティブを使用して設定を行います。

<div id="app">
	<input type="file" v-on:change="handleFile">
	{{ fileData }}
</div>

handleFileメソッドでeventからファイルの情報を取得してfileDataプロパティにその値を設定します。


<script>
var app = new Vue({
  el: '#app',
  data:{
  	fileData: ''
  },
  methods: {
  	handleFile: function(event){
  		file  = event.target.files[0]
  		this.fileData = file
  	}
  }
})
</script>	
ファイル選択画面
ファイル選択画面

ファイルを選択するとchangeイベントにより、filehandleメソッドが実行され、画面にはFileオブジェクトが表示されます。

ファイルを選択後の画面
ファイルを選択後の画面

Fileオブジェクトだけだとわかりにくいので、取得したファイル情報から名前を取得します。画面にはアップロードしたファイル名が表示されます。


this.fileData = file.name	

まとめ

入力フォームに必要な一つ一つの要素を確認していくとvue.jsでの設定がそれほど難しくないことが理解できたかと思います。