はじめに
Vue.js 2.0で、orderBy
、filterBy
が削除された。マイグレーション方法はこちらで各々の方法が提示されているが、両方を組み合わせて使っている場合が分からなかったので、サンプルコードを書いてみた。
サンプルコード
5科目のテストの点数を、高得点での絞り込み、点数順に並び替えるサンプルを例とする。以下に1系、2系両方を用意した。
1系(1.0.26で確認済み)
- フィルターはfilterByを使用する。引数にコールバック関数を渡し、その中で条件判定させることで絞り込みをさせる。
- 並び替えはorderByを使用する。第1引数に、ソートするキーを指定、第2引数に昇順 (order >= 0) または降順 (order < 0) の値を指定する。ここでは、初期値として1を渡すことで昇順としている。
<div id="app">
<a href="#" @click="order = order * -1">並び替え</a>
<a href="#" @click="filterType = 'high'">80点以上</a>
<a href="#" @click="filterType = 'all'">全て</a>
<ul>
<li v-for="item in items | filterBy pointFilter | orderBy 'point' order">
{{ item.title }} / {{ item.point }}点
</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
order: 1,
filterType: 'all',
items: [
{ title: '数学', point: 100 },
{ title: '国語', point: 80 },
{ title: '理科', point: 60 },
{ title: '社会', point: 40 },
{ title: '体育', point: 0 },
]
},
methods: {
pointFilter: function(item) {
if (this.filterType == 'high') {
return item.point >= 80;
}
return true;
}
}
});
2系の場合(2.2.1で確認済み)
<div id="app">
<a href="#" @click="order = order * -1">並び替え</a>
<a href="#" @click="filterType = 'high'">80点以上</a>
<a href="#" @click="filterType = 'all'">全て</a>
<ul>
<li v-for="item in filteredItems">
{{ item.title }} / {{ item.point }}点
</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
order: 1,
filterType: 'all',
items: [
{ title: '数学', point: 100 },
{ title: '国語', point: 80 },
{ title: '理科', point: 60 },
{ title: '社会', point: 40 },
{ title: '体育', point: 0 },
]
},
methods: {
pointFilter: function(items) {
_that = this;
return items.filter(function(item) {
if (_that.filterType == 'high') {
return item.point >= 80;
}
return item.point >= 0;
});
},
pointSort: function(items) {
var order = (this.order == 1) ? 'asc' : 'desc'
return _.orderBy(items, 'point', order);
}
},
computed: {
filteredItems: function() {
var items = this.items;
items = this.pointFilter(items);
items = this.pointSort(items);
return items;
}
}
});
マイグレーション方法
1. computedプロパティから配列を取得する
<li v-for="item in items | filterBy pointFilter | orderBy 'point' order">
<li v-for="item in filteredItems">
2. フィルターは、フィルタリングするメソッドに処理させる
フィルタリングするメソッドをmethods内に用意する。高得点順又は全ての種別によって、itemsをJavaScriptビルドイン関数の.filterを利用してフィルタリングさせる。
pointFilter: function(items) {
_that = this;
return items.filter(function(item) {
if (_that.filterType == 'high') {
return item.point >= 80;
}
return item.point >= 0;
});
}
pointFilter
メソッドをcomputedプロパティで呼び出すことで、フィルタリングができるようになる。
computed: {
filteredItems: function() {
var items = this.items;
items = this.pointFilter(items);
return items;
}
}
3. 並び替えは、並び替えするメソッドに処理させる
実装方法はフィルターとほぼ同じだが、Vue.jsで並び替えができなくなり、移行ガイドではlodashのorderByメソッドの利用が提案されている。なので、itemsをorderByで並び替えるメソッドを用意する。
pointSort: function(items) {
var order = (this.order == 1) ? 'asc' : 'desc'
// _はlodashを使用
return _.orderBy(items, 'point', order);
}
pointFilter
メソッドをcomputedプロパティで呼び出すことで、並び替えができるようになる。
computed: {
filteredItems: function() {
var items = this.items;
items = this.pointSort(items);
return items;
}
}
4. フィルタリング、並び替えメソッドを連続して呼ぶ
フィルタリング、並び替えを処理するメソッドを用意したら、下記のように連続して呼び出すことで両方を組み合わせて利用している場合も移行出来るようになる。
computed: {
filteredItems: function() {
var items = this.items;
items = this.pointFilter(items);
items = this.pointSort(items);
return items;
}
}
おわりに
もうちょっとスマートな記述にしたいが、案が思い浮かばず。もしサンプルコード含め、気になる点があれば遠慮なくコメントやご指摘をお願いします。