Vue.jsでV-forを使用してアイテムを反復処理する方法
紹介
フロントエンドアプリケーションに共通する要件の一つは、アイテムを一覧表示することです。それは、ToDoリストやカードシステムの形を取ることができます。Vue.jsは、組み込みの v-for< コアディレクティブを使用して、アイテムのリストをブラウザにレンダリングすることをサポートしています。
この記事では、Vueアプリケーションでv-forをどのように使用できるかを探ります。
前提条件
この投稿は、JavaScriptにおけるループ、配列、およびオブジェクトに関する知識があることを前提としています。JavaScriptを始めたばかりの方は、このシリーズを参照できます。
この探索は、CDN(コンテンツ配信ネットワーク)にホストされたVue.jsフレームワークのHTMLファイルに基づいています。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for</title>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
new Vue({
el: "#app",
data() {
return {
message: "hello"
}
}
});
</script>
</body>
</html>
Vue.jsを始める際は、この投稿を参照できます。
この時点で、もしこのコードをアップロードしてブラウザでこのファイルを表示すると、メッセージが表示されます: "hello".
v-forを使用した範囲
組み込みのv-forディレクティブを使用すると、アイテムをループ処理することができます。
v-forディレクティブで範囲を使用して、指定された回数繰り返すことができます。
私たちの<div>の内容を、リストアイテムを15回繰り返す順不同リストに置き換えましょう:
<div id="app">
<ul>
<li v-for="item in 15">{{ item }}</li>
</ul>
</div>
これにより、番号が 1 から 15 までの順不同リストが作成されます。
<template>要素の使用
v-for ディレクティブは、付けられた要素にのみ適用されます。複数のアイテムが v-for ディレクティブで繰り返される必要がある場合は、要素を <template> 要素で囲む必要があります。
私たちの<div>の内容を<template>に置き換えましょう:
<div id="app">
<template v-for="item in 15">
<span>{{ item }}</span>
<button>Count</button>
</template>
</div>
これにより、繰り返される<span>と<button>のコレクションが生成されます。
v-forをオブジェクトと一緒に使用する
データモデルの objectItems オブジェクト内の値をループすることができます。これは、繰り返すべき要素に v-for ディレクティブを追加することで実現できます。
data()内の行を修正して、objectItemsオブジェクトを返すようにしましょう:
<script>
new Vue({
el: "#app",
data() {
return {
objectItems: {
key1: 'item1',
key2: 'item2',
key3: 'item3'
}
}
}
});
</script>
<div>の内容をリストアイテムを繰り返す順不同リストに置き換えましょう:
<div id="app">
<ul>
<li v-for="item in objectItems">{{ item }}</li>
</ul>
</div>
これが物事の見え方です:
<div id="app">
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
</div>
これにより、オブジェクトのプロパティ値を持つ順不同のリストが作成されます。
Vueでオブジェクトをループするとき、プロパティ値に加えて、2つの追加パラメータが得られます。つまり、keyとindexの値です。
このkey値は、現在のプロパティのキーにアクセスするためのものです。
このindexはループ内の現在のアイテムのインデックスを提供します。これはループされたリスト内のアイテムの位置です。
私たちの <div> の内容を、item、key、および index を使ってリスト項目を繰り返す無秩序リストに置き換えましょう:
<div id="app">
<ul>
<li v-for="(item, key, index) in objectItems">
{{ item }} - {{ key }} - {{ index }}
</li>
</ul>
</div>
これが物事の見え方です:
<div id="app">
<ul>
<li>item1 - key1 - 1</li>
<li>item2 - key2 - 2</li>
<li>item3 - key3 - 3</li>
</ul>
</div>
これにより、item、key、およびindexを含む順序のないリストが生成されます。
v-forを配列で使用する
データモデルの shoppingItems 配列内のアイテムをループすることができます。これは、繰り返すべき要素に v-for ディレクティブを追加することで実現できます。
データ()内の行を修正して、オブジェクトを含むshoppingItems配列を返すようにしましょう:
<script>
new Vue({
el: "#app",
data() {
return {
objectItems: {
key1: 'item1',
key2: 'item2',
key3: 'item3'
},
shoppingItems: [
{ name: 'apple', price: '7' },
{ name: 'orange', price: '12' }
]
}
}
});
</script>
shoppingItems 配列内のオブジェクトをループ処理し、指定されたキーを使用して値にアクセスできます。
私たちの <div> の内容を、item.name と item.price を繰り返す無秩序リストに置き換えましょう:
<div id="app">
<ul>
<li v-for="item in shoppingItems">
{{ item.name }} - {{ item.price }}
</li>
</ul>
</div>
これが物事の見え方です。
<div id="app">
<ul>
<li>apple - 7</li>
<li>orange - 12</li>
</ul>
</div>
これは配列の値を含む順序なしリストになります。
v-bind:keyを使用して要素を追跡する
配列の順序が変更されると、デフォルトではVueは既存の各要素内のデータを変更しますが、DOM要素を更新された位置に移動させることはありません。
Vueはそれぞれの要素をキーを使って追跡するように設定できます。これにより、値を置き換えるのではなく要素を移動させることになります。
この値は、イテレーションされているそれぞれの要素に対して一意であるべきです。
item.nameを使ってキーを割り当てましょう:
<div id="app">
<ul>
<li v-for="item in shoppingItems" v-bind:key="item.name">
{{ item.name }} - {{ item.price }}
</li>
</ul>
</div>
現在、Vueは変更が行われる際にノードのアイデンティティを追跡する方法を持っています。
変更の管理
ボックスから出して、v-forは配列の変更メソッドをサポートしています。これらは、push、pop、shift、unshift、splice、sort、およびreverseです。これらの操作のいずれかが配列に対して実行されると、v-forディレクティブは新しいデータでビューを更新します。
また、新しい配列で配列を置き換えるとき、Vueはアイテムを更新する最も最適化された方法を見つけます。
変更管理の問題
Vueが配列内で変更された時に追跡できない2つのことは:
- アイテムを直接設定する。
例 :
data.shoppingItems[3] = { price: 10, name: 'pineapple' };
これは Vue.set メソッドを使用することで解決できます。このメソッドは、array、index、および new value を受け入れます。
Vue.set(data.shoppingItems, 3, { price: 10, name: 'pineapple' });
また、指定したインデックスに値を設定するために splice を使用することもできます。
- 配列の長さを変更する。
例 :
data.shoppingItems.length = 2;
問題を避けるために、配列の長さを直接設定するのではなく、spliceを使用して配列の長さを変更できます。
リストのフィルタリング
元のリストを変更することなく表示されているリストをフィルタリングできます。これは、computed 値を使用するか、メソッドを持ち、v-for 値を設定する際に値を渡すことで実行できます。
computed 値を使用してアイテムをフィルタリングする
リストに直接値を設定する代わりに、computed値を参照します。その計算関数内でデータをフィルタリングするロジックを書くことができます。
まず、itemsLessThanTenを定義しましょう:
<script>
new Vue({
el: "#app",
data() {
return {
objectItems: {
key1: 'item1',
key2: 'item2',
key3: 'item3'
},
shoppingItems: [
{ name: 'apple', price: '7' },
{ name: 'orange', price: '12' }
]
}
},
computed: {
itemsLessThanTen: function() {
return this.shoppingItems.filter(function(item) {
return item.price < 10;
})
}
}
});
</script>
それでは、itemsLessThanTenを使用するようにv-forを変更しましょう:
<div id="app">
<ul>
<li v-for="item in itemsLessThanTen" v-bind:key="item.name">
{{ item.name }} - {{ item.price }}
</li>
</ul>
</div>
これが物事の見え方です。
<div id="app">
<ul>
<li>apple - 7</li>
</ul>
</div>
itemLessThanTen 関数は、JavaScript の filter 関数を使用して、価格が 10 未満のアイテムを返します。
アイテムをフィルタリングする方法を使用する
このアプローチでは、同じshoppingItemsリストを私たちが定義したメソッドに直接渡します。これにより、配列内のすべてのアイテムがメソッドの定義に従ってフィルタリングされます。
まず、filterItemsを定義しましょう:
<script>
new Vue({
el: "#app",
data() {
return {
objectItems: {
key1: 'item1',
key2: 'item2',
key3: 'item3'
},
shoppingItems: [
{ name: 'apple', price: '7' },
{ name: 'orange', price: '12' }
]
}
},
computed: {
itemsLessThanTen: function() {
return this.shoppingItems.filter(function(item) {
return item.price < 10;
})
}
},
methods: {
filterItems: function(items) {
return items.filter(function(item) {
return item.price < 10;
})
}
}
});
</script>
では、v-forをfilterItemsを使うように修正しましょう:
<div id="app">
<ul>
<li v-for="item in filterItems(shoppingItems)" v-bind:key="item.name">
{{ item.name }} - {{ item.price }}
</li>
</ul>
</div>
これが物事の見え方です:
<div id="app">
<ul>
<li>apple - 7</li>
</ul>
</div>
filterItems メソッドは computed 値の例と同じ機能を果たし、最終結果は同じになります。
結論
この記事では、Vueアプリケーションでのv-forの使用について学びました。範囲、キー、computed、およびmethodsについて紹介されました。
Vue.jsについてさらに学びたい場合は、演習やプログラミングプロジェクトのためのVue.jsトピックページをご覧ください。
