サイトトップ

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

HTML5テクニカルノート

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


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

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

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

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

図001

入力フィールドの右に、つぎのように「追加」の<button>要素を加えます(図002)。入力フィールドの<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 class="btn btn-primary btn-sm">追加</button>
	</p>
</div>

<script>要素

const app = new Vue({
	data: {
		todoText: '',
		todos: [

		]
	}

});

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

図002

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

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

<body>要素

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

	<p>

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

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

<script>要素

const app = new Vue({
	data: {
		todoText: '',
		todos: [

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

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

<script>要素

const app = new Vue({

	methods: {
		addTodo: function() {
			const 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>要素

const app = new Vue({
	data: {
		todoText: '',
		todos: [
			{text: 'Vue.jsを学ぶ', done: true},
			{text: 'Vue.jsでアプリケーションをつくる', done: false},
		]
	},
	methods: {
		addTodo() {
			const newTodo = this.todoText;
			this.todoText = '';
			this.todos.push(
				{text: newTodo, done: false}
			);
		}
	}
});
document.addEventListener('DOMContentLoaded', () =>
	app.$mount('#app')
);

03 Vueディレクティブの省略記法とECMAScript 2015のスプレッド構文を使う

Vue.jsのアプリケーションには、必ずといってよいほど用いられるディレクティブがふたつあります。v-bind:v-on:です。そのため、つぎのような省略記法が用意されています。これらを使えば、前掲コード001は以下のように簡略に書けるのです。

<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のスプレッド構文・残余引数・分割代入を使ってみる」「スプレッド構文」参照)。いわば、配列の角かっこ[]を取り去って、カンマ(,)区切りの値にしてしまうということです。配列のコピーをつくったり、複数の配列をつなげたりすることが簡単にできます。大きな特長は、もとの配列を書き替えないということです。つぎのコードのように、Array.prototype.push()メソッドの替わりにも使えます。もっとも、この場合はもとの配列(todos)を上書きしますので、あえて使わなくても構いません。

<script>要素

const app = new Vue({

	methods: {
		addTodo() {

			// this.todos.push(
			this.todos = [
				...this.todos,
				{text: newTodo, done: false}
			];
			// );
		}
	}
});

前掲コード001を書き改めたのが、つぎのコード002です。アプリケーションの動きは変わりません。動きが確かめられるように、以下にサンプル002を掲げました。

コード002■Vueディレクティブの省略記法とECMAScript 2015のスプレッド構文を使う

<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({
	data: {
		todoText: '',
		todos: [
			{text: 'Vue.jsを学ぶ', done: true},
			{text: 'Vue.jsでアプリケーションをつくる', done: false},
		]
	},
	methods: {
		addTodo() {
			const newTodo = this.todoText;
			this.todoText = '';
			this.todos = [
				...this.todos,
				{text: newTodo, done: false}
			];
		}
	}
});
document.addEventListener('DOMContentLoaded', () =>
	app.$mount('#app')
);

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

See the Pen Vue.js + ES6: Adding text in a input field to the list by Fumio Nonaka (@FumioNonaka) on CodePen.

Vue.js + ES6


作成者: 野中文雄
作成日: 2019年6月1日 FN1702007「Vue.js入門 04: フィールドに入力したテキストを動的に項目として加える」を全面改訂。


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