サイトトップ

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

HTML5テクニカルノート

Vue.js入門 05: 項目を数えて表示する


Vue.jsには、普通のプロパティとメソッドのほか、プロパティのように扱えるメソッドが備わっています。そのプロパティで、条件に合ったデータを数えて返してみます。

[注記] 本稿はVue.js 2.6とECMAScript 2015(ES6)にもとづく「Vue.js + ES6入門 05: 項目を数えて表示する」に改訂しました。

01 項目の数を示す

「Vue.js入門 04: フィールドに入力したテキストを動的に項目として加える」でつくったコード001に手を加えてゆきましょう。アプリケーションに納めた複数のデータがリストとして示され、入力フィールドのテキストは「追加」ボタンで項目に加えられます(図001)。これら項目のすべてとチェックされていない数を、それぞれ調べて表示するのが課題です。

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

図001

項目のデータは以下のように、配列のプロパティに納められています。ですから、Array.lengthプロパティで調べられます。HTMLの要素には、二重波かっこ{{}}でバインディングすればよいでしょう。これで、項目の総数は示せます(図002)。

<body>要素

<div id="app" class="container">
	<h2>Todo</h2>
	<p>
		全{{todos.length}}件
	</p>

</div>

<script>要素

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

		todos: [
			{text: 'Vue.jsを学ぶ', done: true},
			{text: 'Vue.jsでアプリケーションをつくる', done: false},
		]
	},

});

図002■項目の総数が示された

図002

02 条件に合ったデータを数えて返す

チェックをつけた項目は、データのプロパティ(done)の値がtrueになります。その数を調べて返すというのは、メソッドに定める処理です。けれど、Vue.jsでは、つぎのようにプロパティ(remaining)のかたちにできます(getter関数)。

<body>要素

<div id="app" class="container">
	<h2>Todo</h2>
	<p>
		全{{todos.length}}件中残り{{remaining}}件
	</p>

</div>

Vue()コンストラクタの引数オブジェクトには、つぎのように算出プロパティcomputedを加えます。関数を与えたプロパティ(remaining)はgetter関数として働きます。関数本体で扱っているデータが変われば、戻り値も改められるのです。上記の要素にバインドしたテキストには、つねに最新の値が示されることになります(図003)。HTMLとJavaScriptの記述は、以下のコード001にまとめました。併せて、コードを試すためのサンプル001もその下に掲げてあります。

<script>要素

var app = new Vue({
	el: '#app',

	computed: {
		remaining: function() {
			var count = 0;
			var todos = this.todos;
			var length = todos.length;
			for(var i = 0; i < length; i++) {
				if(!todos[i].done) {
					count++;
				}
			}
			return count;
		}
	}
});

図003■つねに最新の項目数が示される

図003

コード001■条件に合ったデータを数えて返す

<body>要素

<div id="app" class="container">
	<h2>Todo</h2>
	<p>
		全{{todos.length}}件中残り{{remaining}}件
	</p>
	<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 = '';
		}
	},
	computed: {
		remaining: function() {
			var count = 0;
			var todos = this.todos;
			var length = todos.length;
			for(var i = 0; i < length; i++) {
				if(!todos[i].done) {
					count++;
				}
			}
			return count;
		}
	}
});

サンプル001■条件に合ったデータを数えて返す

See the Pen Vue.js: Using Computed Properties by Fumio Nonaka (@FumioNonaka) on CodePen.

03 算出プロパティとメソッドの違い

computedに加えた算出プロパティ(remaining)は、methodsに以下のようにメソッド(getRemains())として定めても、同じ結果が得られます。

<body>要素

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

	<p>
		<!--全{{todos.length}}件中残り{{remaining}}件-->{{todos.length}}件中残り{{getRemains()}}件

	</p>

</div>

<script>要素

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

		todos: [
			{text: 'Vue.jsを学ぶ', done: true},
			{text: 'Vue.jsでアプリケーションをつくる', done: false},
		]
	},
	methods: {

		getRemains: function() {  // 算出プロパティのgetter関数と同じ処理
			var count = 0;
			var todos = this.todos;
			var length = todos.length;
			for(var i = 0; i < length; i++) {
				if(!todos[i].done) {
					count++;
				}
			}
			return count;
		}
	}
});

けれど、今回の例では「算出プロパティは依存関係にもとづきキャッシュされる」のでお得です。依存するデータが変わらないかぎり前に求めた値を返し、プロパティに定めたgetter関数は呼び出されないからです。

04 Advanced: ECMAScript 6の構文を使う

「Vue.js入門 04: フィールドに入力したテキストを動的に項目として加える」のコード001は、その項03「Advanced: Vueの省略記法とECMAScript 6の構文を使う」でECMAScript 6準拠のコード002に改めました。前掲コード001も本稿で加えた処理を、同じようにECMAScript 6の構文で書いてみましょう。まず、算出プロパティcomputedに加えるのはメソッドですから、以下のように「: function」は省けます(前出「Vue.js入門 04」03「Advanced: Vueの省略記法とECMAScript 6の構文を使う」参照)。

つぎにメソッド(remaining())本体は、変数をletもしくはconstで宣言すれば、forループの処理はそのままでも構いません。けれど、ここではECMAScript 5.1で備わったArray.filter()メソッドを使ってみることにしましょう。引数に渡した関数は、配列要素を順に受け取ります。そして、戻り値がtrueとなる要素のみの納められた配列を返します。そして、名前のない関数には、つぎのようにアロー関数式=>が使えるのです。関数本体が戻り値を返す文ひとつであれば、ブロックの波かっこ{}returnステートメントも省けます。

<script>要素

const app = new Vue({

	computed: {
		// remaining: function() {
		remaining() {
			/* var count = 0;
			var todos = this.todos;
			var length = todos.length;
			for(var i = 0; i < length; i++) {
				if(!todos[i].done) {
					count++;
				}
			}
			return count; */
			return this.todos.filter((todo) => !todo.done).length;
		}
	}
});

<body>要素のHTMLコードは前掲コード001と同じです。ECMAScript 6の構文に書き改めたJavaScriptコードは、つぎのコード002のとおりです。動きを確かめるための以下のサンプル002をjsdo.itに掲げました。

コード002■ECMAScript 6の構文で条件に合ったデータを数えて返す

<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 = '';
		}
	},
	computed: {
		remaining() {
			return this.todos.filter((todo) => !todo.done).length;
		}
	}
});

サンプル002■Vue.js + ES6: Counting items to match conditions and return the number


作成者: 野中文雄
更新日: 2017年11月25日 04「Advanced: ECMAScript 6の構文を使う」を追加。
更新日: 2016年2月22日 03「算出プロパティとメソッドの違い」を追加。
作成日: 2016年2月18日


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