サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

Vue.js入門 04: フィールドに入力したテキストを動的に項目として加える


Vue.jsは、入力とアプリケーションの状態を結びつける双方向バインディングが簡単にできます。リストをつくる項目のデータに追加すれば、ページのリストも書き替わるのです。

[注記] 本稿はVue.js 2.6とECMAScript 2015(ES6)にもとづく「Vue.js + ES6入門 04: フィールドに入力したテキストを動的に項目として加える」に改訂しました。

01 入力フィールドに追加ボタンを加える

「Vue.js入門 03: データから動的にリストをつくる」でつくったコード001に手を加えてゆきましょう。アプリケーションに納めた複数のデータがリストとして示され、入力フィールドのテキストは初めの項目とバインドされています(図001)。これを、入力フィールドから項目が加えられるように書き替えます。

図001■入力フィールドのテキストがページの項目に示される

図001

入力フィールドの右に、つぎのように「追加」の<button>要素を加えます(図002)。ディレクティブv-on:clickは、クリックしたとき実行するJavaScriptコードの定めです。あとで、詳しくご説明します。入力フィールドの<input>要素(type属性"text")のv-modelディレクティブには新たなプロパティ(todoText)を与え、以下のようにVue()コンストラクタに渡す引数オブジェクトのdataプロパティに加えました。

<body>要素

<div id="app" class="container">

	<p>
		<!--<input type="text" v-model="todos[0].text" placeholder="add new todo here" />-->
		<input type="text" v-model="todoText" placeholder="add new todo here" />
		<button v-on:click="addTodo()" class="btn btn-primary btn-sm">追加</button>
	</p>
</div>

<script>要素

var app = new Vue({
	el: '#app',
	data: {
		todoText: '',
		todos: [

		]
	}

});

図002■入力フィールドの右に「追加」ボタンが加わった

図002

02 入力フィールドの項目をデータに加える

「追加」ボタンをクリックしたら、入力フィールドのテキストを項目としてデータ配列に加えましょう。v-onディレクティブはコロン(:)のあとに引数として添えたイベントに、リスナーが定められます。クリックのイベントはclickです。つぎのようにメソッド(addTodo())を呼び出すことにします。

<body>要素

<div id="app" class="container">

	<p>
		<input type="text" v-model="todoText" placeholder="add new todo here" />
		<button v-on:click="addTodo()" class="btn btn-primary btn-sm">追加</button>
	</p>
</div>

メソッド(addTodo())は、Vue()コンストラクタに渡す引数オブジェクトに、methodsプロパティでつぎのように定めます。入力フィールドのテキストにバインドされたプロパティ(todoText)の値を、データ配列(todos)に項目として加え、テキストは空にしました。

<script>要素

var app = new Vue({
	el: '#app',
	data: {
		todoText: '',
		todos: [

		]
	},
	methods: {
		addTodo: function() {
			var newTodo = this.todoText;

			this.todos.push(
				{text: newTodo, done: false}
			);
			this.todoText = '';
		}
	}
});

これで「追加」ボタンを押すと入力フィールドのテキストがデータに項目として加わり、ページのリストは改められます(図003)。<body>要素の記述は、以下のコード002にまとめました。併せて、コードを試すためのサンプル001もその下に掲げてあります。なお、つぎのようにString.trim()メソッドを用いて、空白だけの入力は防ぐようにしました。

<script>要素

var app = new Vue({

	methods: {
		addTodo: function() {
			var newTodo = this.todoText.trim();
			if (!newTodo) {return;}

		}
	}
});

図003■「追加」ボタンで入力フィールドの項目が加わる

図003

コード001■入力フィールドのテキストを「追加」ボタンでページの項目に加える

<body>要素

<div id="app" class="container">
	<h2>Todo</h2>
	<ul class="list-unstyled">
		<li v-for="todo in todos">
			<label>
				<input type="checkbox" v-model="todo.done" />
				<span v-bind:class="{'done': todo.done}">{{todo.text}}</span>
			</label>
		</li>
	</ul>
	<p>
		<input type="text" v-model="todoText" placeholder="add new todo here" />
		<button v-on:click="addTodo()" class="btn btn-primary btn-sm">追加</button>
	</p>
</div>
<script>
var app = new Vue({
	el: '#app',
	data: {
		todoText: '',
		todos: [
			{text: 'Vue.jsを学ぶ', done: true},
			{text: 'Vue.jsでアプリケーションをつくる', done: false},
		]
	},
	methods: {
		addTodo: function() {
			var newTodo = this.todoText.trim();
			if (!newTodo) {return;}
			this.todos.push(
				{text: newTodo, done: false}
			);
			this.todoText = '';
		}
	}
});
</script>

サンプル001■入力フィールドのテキストを「追加」ボタンでページの項目に加える

See the Pen Vue.js: Adding Data to the List by Fumio Nonaka (@FumioNonaka) on CodePen.

03 Advanced: Vueの省略記法とECMAScript 6の構文を使う

応用のテーマとして、前掲コード001の動きはそのままに、構文を洗練させましょう。まず、Vue.jsの省略記法を使います。必ずといってよいほど用いられるふたつのディレクティブv-bind:v-on:は、それぞれつぎのように:@に替えてしまえるのです。

<body>要素

<div id="app" class="container">

	<ul class="list-unstyled">
		<li v-for="todo in todos">

			<!--<span v-bind:class="{'done': todo.done}">{{todo.text}}</span>-->
			<span :class="{'done': todo.done}">{{todo.text}}</span>

		</li>
	</ul>
	<p>

		<!--<button v-on:click="addTodo()" class="btn btn-primary btn-sm">追加</button>-->
		<button @click="addTodo()" class="btn btn-primary btn-sm">追加</button>
	</p>
</div>

つぎにJavaScriptコードは、新しいECMAScript 2015いわゆるECMAScript 6の構文に書き替えます。変数のvar宣言はブロックスコープをもたないので、それが備わったlet、さらに値が上書きされない定数にはつぎのようにconstを用いるのがよいでしょう(ただし、定数の値がオブジェクトの場合にプロパティは書き替えられます)。もうひとつ、オブジェクトに定めるメソッドから「: function」が省けるようになりました。

<script>要素

// var app = new Vue({
const app = new Vue({

	methods: {
		// addTodo: function() {
		addTodo() {
			// var newTodo = this.todoText.trim();
			const newTodo = this.todoText.trim();

		}
	}
});

前掲コード001を書き改めたのが、つぎのコード002です。併せて、動きが確かめられるように、以下のサンプル002をjsdo.itに掲げました。

コード002■Vueの省略記法とECMAScript 6の構文で入力フィールドのテキストをページの項目に加える

<body>要素

<div id="app" class="container">
	<h2>Todo</h2>
	<ul class="list-unstyled">
		<li v-for="todo in todos">
			<label>
				<input type="checkbox" v-model="todo.done" />
				<span :class="{'done': todo.done}">{{todo.text}}</span>
			</label>
		</li>
	</ul>
	<p>
		<input type="text" v-model="todoText" placeholder="add new todo here" />
		<button @click="addTodo()" class="btn btn-primary btn-sm">追加</button>
	</p>
</div>
<script>
const app = new Vue({
	el: '#app',
	data: {
		todoText: '',
		todos: [
			{text: 'Vue.jsを学ぶ', done: true},
			{text: 'Vue.jsでアプリケーションをつくる', done: false},
		]
	},
	methods: {
		addTodo() {
			const newTodo = this.todoText.trim();
			if (!newTodo) {return;}
			this.todos.push(
				{text: newTodo, done: false}
			);
			this.todoText = '';
		}
	}
});
</script>

サンプル002■Vue.js + ES6: Adding text in a input field to the todo list


作成者: 野中文雄
更新日: 2017年11月24日 03「Advanced: Vueの省略記法とECMAScript 6の構文を使う」を追加。
作成日: 2016年2月17日


Copyright © 2001-2017 Fumio Nonaka.  All rights reserved.