Vue.jsのv-forでの並び順を指定したキーの値順にしたり、昇順、降順を切り替えたりする
はじめに
Vue.jsで使用できるv-forは簡単にリストレンダリングできとても便利です。ただ、レンダリングの順番を指定したキーで並べ替えたり、昇順と降順を切り替えるにはcomputedやmethodを用意する必要があります。ここではアルファベット順や数値順で並べ替えるためのフィルターやメソッドをについてメモします。
前提と環境
ここでのVue.jsアプリは、Vue CLIのcreate
コマンドによって作成したデフォルトの状態です。Vue.jsアプリの作成手順は、Windows10(WSL使用)でVue.jsアプリを作成するまでの手順にまとめています。
- Vue.jsアプリはWindows10 + WSL + Ubuntu上で動作
- Node.js、Vue CLI(3系)はインストール済とする
- Vue.jsアプリはVue CLIで作成済。(router、scssなどの機能を指定して作成)
Vue.jsアプリフォルダのツリー構造は以下のようになっています。以降の説明では以下のHome.vue
だけをいじって説明します。
├── babel.config.js
├── node_modules
├── package.json
├── package-lock.json
├── public
├── README.md
└── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ └── HelloWorld.vue
├── main.js
├── router.js
└── views
├── About.vue
└── Home.vue
また、ここでは以下のオブジェクトをv-for
でリストレンダリングする想定で説明します。
items:[
{
id: 1,
name: 'aaa',
email: 'AAA@test.local',
message: 'This is AAA message',
amount: 80,
},
{
id: 2,
name: 'BBB',
email: 'BBB@test.local',
message: 'This is BBB message',
amount: 40,
},
{
id: 3,
name: 'CCC',
email: 'CCC@test.local',
message: 'This is CCC message',
amount: 100,
},
]
要素の順番通りにレンダリングする
まずはデフォルトの状態でレンダリングするために以下のようなコードを使います。以下は、Home.vue
です。
<template>
<div class="home container">
<section style="margin-bottom: 20px;" v-for="item in items" v-bind:key="item.id">
<div class="card">
<header class="card-header">
<p class="card-header-title">{{ item.name }} - {{ item.amount }}</p>
<a href="#" class="card-header-icon" aria-label="more options">
<span class="icon">
<i class="fas fa-angle-down" aria-hidden="true"></i>
</span>
</a>
</header>
<div class="card-content">
<div class="content">{{ item.message }}
<a href="#">{{ item.email }}</a>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
export default {
name: 'home',
data() {
return {
items:[
{
id: 1,
name: 'aaa',
email: 'AAA@test.local',
message: 'This is AAA message',
amount: 80,
},
{
id: 2,
name: 'BBB',
email: 'BBB@test.local',
message: 'This is BBB message',
amount: 40,
},
{
id: 3,
name: 'CCC',
email: 'CCC@test.local',
message: 'This is CCC message',
amount: 100,
},
],
}
},
}
</script>
ブラウザからアクセスしてみると、以下のような表示になります。
続いて、これを配列の要素を逆順から並べてみます。
要素の後ろからリストレンダリングする
配列の後ろからリストレンダリングするには、computed
で配列をの順番を入れ替えて、その配列をreverseItems()
という関数をcomputed
に用意し、それをv-for
に渡します。他は全く一緒です。
<template>
<div class="home container">
<section style="margin-bottom: 20px;" v-for="item in reverseItems" v-bind:key="item.id">
<div class="card">
<header class="card-header">
<p class="card-header-title">{{ item.name }} - {{ item.amount }}</p>
<a href="#" class="card-header-icon" aria-label="more options">
<span class="icon">
<i class="fas fa-angle-down" aria-hidden="true"></i>
</span>
</a>
</header>
<div class="card-content">
<div class="content">{{ item.message }}
<a href="#">{{ item.email }}</a>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
export default {
name: 'home',
data() {
return {
items:[
{
id: 1,
name: 'aaa',
email: 'AAA@test.local',
message: 'This is AAA message',
amount: 80,
},
{
id: 2,
name: 'BBB',
email: 'BBB@test.local',
message: 'This is BBB message',
amount: 40,
},
{
id: 3,
name: 'CCC',
email: 'CCC@test.local',
message: 'This is CCC message',
amount: 100,
},
],
}
},
computed: {
// 配列の要素順番を逆順にする
reverseItems() {
return this.items.slice().reverse();
},
}
}
</script>
なお、上記のreverseItems()
の中のitems
はdata
の中のitems
です。もし各自で使う場合は、ここをそれぞれのオブジェクト名に置き換えてください。
以下のような表示になります。配列の後ろから順番に表示されていることがわかります。
次はitems
の中のamount
の昇順、降順で表示します。
指定したキーの数値でリストレンダリングする
例としてitems
の中のamount
で並べ替えて表示してみます。同じくcomputed
で以下のようにsortedItemsByAmount()
という関数を用意し、それをv-for
に渡します。
<template>
<div class="home container">
<section style="margin-bottom: 20px;" v-for="item in sortedItemsByAmount" v-bind:key="item.id">
(途中省略。前節のコードと全く同じです。)
computed: {
// amountで並べ替え
sortedItemsByAmount(){
return this.items.sort((a, b) => {
return (a.amount < b.amount) ? -1 : (a.amount > b.amount) ? 1 : 0;
});;
}
}
上記のsortedItemsByAmount()
の中のitems
はdata
の中のitems
、amount
もitems
のキーです。各自で使う場合は、それぞれのオブジェクト名、キー名に置き換えてください。
以下のような表示になります。amount
の昇順で表示されます。
もしamount
の降順で表示したい場合は、以下のようにsortedItemsByAmount()
の中の数値の-1
と1
を入れ替えます。
sortedItemsByAmount(){
return this.items.sort((a, b) => {
return (a.amount < b.amount) ? 1 : (a.amount > b.amount) ? -1 : 0; // -1と1を入れ替え
});;
}
なぜこれで昇順、降順が入れ替わるか、sort
関数については以下の参考サイト様がわかりやすいです。
次はアルファベット順番に並べる場合について説明します。
アルファベット順でリストレンダリングする
例としてitems
の中のname
で並べ替えて表示してみます。computed
にsortedItemsByName()
という関数を用意し、それをv-for
に渡します。なお、以下は大文字、小文字を区別せずに並べ替える場合です。
<template>
<div class="home container">
<section style="margin-bottom: 20px;" v-for="item in sortedItemsByName" v-bind:key="item.id">
(途中省略。前節のコードと全く同じです。)
computed: {
sortedItemsByName(){
return this.items.sort((a, b) => {
let textA = a.name.toUpperCase();
let textB = b.name.toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});;
},
}
上記のsortedItemsByAmount()
の中のitems
はdata
の中のitems
、name
もitems
のキーです。各自で使う場合は、それぞれのオブジェクト名、キー名に置き換えてください。
ここの例では、表示は冒頭に載せた場合の配列の要素順と同じになるので省略します。もしアルファベットで降順にしたい場合(Z→A)は、前節と同じようにsortedItemsByName()
の中の数値の-1
と1
を入れ替えます。
sortedItemsByName(){
return this.items.sort((a, b) => {
let textA = a.name.toUpperCase();
let textB = b.name.toUpperCase();
return (textA < textB) ? 1 : (textA > textB) ? -1 : 0; // -1と1を入れ替え
});;
}
もし大文字と小文字を区別して並べ替えたい場合は、すでに述べた指定したキーの数値で並べ替える方法をそのまま使えば実現できます。昇順では小文字から大文字、降順では大文字から小文字で並べ替えされます。具体的には、以下のようにsortedItemsByAmount()
のキー名をamount
からname
に変更するだけでOKです。
sortedItemsByAmountName(){
return this.items.sort((a, b) => {
return (a.name < b.name) ? -1 : (a.name > b.name) ? 1 : 0;
});;
}
最後に、昇順と降順を切り替えるためのボタンを実装してみます。
昇順、降順を切り替えるためのボタンを実装する
すでに述べたように、昇順と降順を切り替えるには、単純にcomputed
に用意した各関数内にあるsort
内の1
と-1
を切り替えればOKです。したがって、例えば、sortOrder
という値と以下のようなメソッドを用意します。
data() {
return {
items:[... 省略...],
sortOrder: 1
}
},
(途中省略)
methods: {
changeOrder(){
this.sortOrder = this.sortOrder > 0 ? -1 : 1;
},
}
さらに、これまでに説明したsortedItemsByAmount()
、 sortedItemsByName()
の中の数値の1
をthis.sortOrder
に変更します。例えばsortedItemsByAmount()
の場合は以下のようになります。
sortedItemsByAmount(){
return this.items.sort((a, b) => {
return (a.amount < b.amount) ? -this.sortOrder : (a.amount > b.amount) ? this.sortOrder : 0;
});;
},
あとはクリックすることで上記のchangeOrder
を呼び出すボタンを例えば以下のように用意します。
<button class="button" @click="changeOrder">順番切り替え</button>
ボタンをクリックしてみると、昇順と降順が入れ替わることを確認できると思います。もちろん、ボタンではなくリンクをクリックした場合などにchangeOrder
を呼び出しても同じです。
まとめ
Vue.jsのv-forでのリストレンダリングの順番を操作する方法をまとめました。
関連記事
- 公開日:2019/09/11 更新日:2019/09/11
Nuxt.jsで使っているBuefyのスタイルをカスタマイズする
Nuxt.jsでBuefyを使っており、部分的にスタイルをカスタマイズしたい場面がありました。この記事では、Nuxt.jsで使っているBuefyのスタイルをカスタマイズする方法をまとめます。
- 公開日:2019/06/15 更新日:2019/06/15
Electron + Vue.js アプリでSQLite3を使う手順
Electron + Vue.jsで構築したデスクトップアプリでSQLite3を使うための手順をまとめます。
- 公開日:2019/06/13 更新日:2019/06/13
Electron + Vue.jsで画面をPDF化する手順
Electron + Vue.jsで構築したデスクトップアプリで画面をPDF化するための手順をまとめます。
- 公開日:2018/11/30 更新日:2018/11/30
Vue.jsアプリをNow(zeit.co)にデプロイするまでの手順と使い方
Nowは非常にシンプルなPaaSです。他のPaaSと比較しても必要な設定やデプロイまでの作業が非常に簡単になっています。この記事では、ローカルにあるVue.jsアプリをNow上にデプロイし、実際にブラウザからアクセスしてみるところまでの手順をメモします。
- 公開日:2018/11/27 更新日:2018/11/27
Vue.jsからFirestoreを使うための準備とFirestoreへのデータ書き込み手順
FirebaseのCloud Firestore(以降、Firestore)とVue.jsを組み合わせると、データ書き込みや読み込みが非常に簡単に実行できます。ここでは、Vue.jsで簡素なフォームを作成し、そのフォームからFirestoreにデータを書き込むところまでをメモします。