Vue.js 2.xのフィルタについて調べてみた

# はじめに
今年、東京で行われたPHPカンファレンスでVue.jsの講演をたまたま聞き、
そこで最近(日本時間：2016/10/1)、Vue.jsのバージョンが2.0にUPDATEされたと知り、始めるなら今でしょということでJS初心者だがちょっとかじってみました。

アホなので、最初は自分がやりたい処理をVue.jsハイフンとググって、コードをコピペして、動かんぞ！ということで、どうしたことだとドキュメントを読み始めました。
読んでみて(まだ途中)、Vue1.xとVue2.xでは結構違うということを知りました。
そこで、特に気になったフィルタの書き方の違いについて少しまとめることにしました。

# フィルタ
## Vue1.x
Vue1.xでは、箇条書きすると
・capitalize
・uppercase
・lowercase
・currency
・pluralize
・json
・debounce
・limitBy
・filterBy
・orderBy
といったbuilt-inのフィルタを
フィルタ別に、mustache展開{{}}やv-on,v-forといったディレクティブで使用することができました。
## Vue2.x
Vue2.xでは、上のVue1.xのbuilt-inのフィルタすべて使えなくなりました。

Vue2.xでVue1.xで使うことができたbuilt-inのフィルタを使いたい場合には、
JSコードやサードパーティを使い、代わりに使ったり、
またlimitBy,filterBy,orderByに関してはcomputedプロパティもしくはメソッドとして定義してやる必要があります。

Vue1.xのlimitBy,filterBy,orderByは初めたばかりの僕としては超便利だなと思うのですが、
[公式サイト](https://jp.vuejs.org/v2/guide/migration.html#フィルタ外でのテキスト展開-削除)をみると
>
フィルタは、今やテキスト内での補完({{ }} タグ)のみで使用することができます。今までの v-model
や v-on ディレクティブ上でのフィルタリングは、それ自体の利便性よりも、コードの複雑化につなが
ることのほうが多いことに気がつきました。v-for 上でのリストのフィルタリングについては、それを
コンポーネント上で再利用可能とするために、算出プロパティとして JavaScript 上のそのロジックを
移動させるようにしても良いでしょう。フィルタは、今やテキスト内での補完({{ }} タグ)のみで使用
することができます。今までの v-model や v-on ディレクティブ上でのフィルタリングは、それ自体
の利便性よりも、コードの複雑化につながることのほうが多いことに気がつきました。v-for 上でのリ
ストのフィルタリングについては、それをコンポーネント上で再利用可能とするために、算出プロパテ
ィとして JavaScript 上のそのロジックを移動させるようにしても良いでしょう。


とありますように、
利便性よりもコードの複雑化阻止ということで無くしたそうです。
ただし代替となるcomputedプロパティを使った書き方はあるということです。
上の公式サイトを見てもらえればいくつもの例がのっています。


## フィルタの3つの表現方法
1. computedプロパティを使う
2. filtersプロパティを使う
3. グローバルにfilterを定義する

以下ではそれらについて説明します。

## 1. computedプロパティを使う
v-forディレクティブなどで利用できるVue1.xのlimitBy,filterBy,orderByは、computedプロパティ
で代替として定義できます。
またcomputedプロパティで別のルールを定義することもできます。
あとで説明する、mustache展開{{}}の中で使うフィルタは、v-forディレクティブの中で
使えないので、これはlimitBy,filterBy,orderByを定義したいという以外にもかなり使えそうです。

具体例としてVue.1xのlimitByの場合とVue2.xでcomputedプロパティを使った表現方法を書きました。
ちなみにlimitByとは、
limitBy N
で配列の要素数をN個に制限できちゃいます。

JS側は共通で

```js
new Vue({
    el: '.hoge',
    data: {
        persons: [
            { "name" => "hogetaro" },
            { "name" => "hogejiro" },
            { "name" => "hogeko" },
            { "name" => "hogezaburo" }
        ]
    },
    computed: {
        filteredPerson: function() {
            return this.persons.slice(0, 3);
        }
    }
})
```
とします。

Vue1.xではHTML側を

```html
<ul class="hoge">
    <li v-for="person in persons | limitBy 3">{{ person.name }}</li>
</ul>
```
とします。これで配列personsの要素数が3個に制限されてしまいました。

```html
・hogetaro
・hogejiro
・hogeko
```
と出力されます。

一方で、Vue2.xでは
HTML側を

```html
<ul class="hoge">
    <li v-for="person in filteredPerson">{{ person.name }}</li>
</ul>
```
とします。
filteredPersonというcomputedプロパティを定義し、
その中で、this.persons.slice(0,3)と書いてあり、配列を切り取っているのがわかると思います。thisはVueインスタンスを指します。

## 2. filtersプロパティ
Vue2.xではフィルタは二つの場所で使用することができます。
1.mustache 展開 {{}}
2.v-bind 式 (2.1.0 以降のサポート)
の2つです。
基本的には、{{}}の中でのみフィルタは使えるのだが、v-bind式のみ2.1.0以降フィルタを
使えるようです。

mustache 展開{{}}の中で使うとき、
次のようにパイプ|つけてやる。

```html
{{ person.name | filterPerson }}
```
そして
JS側で、filtersプロパティを定義する

```js
new Vue({
    // ..省略
    filters: {
        filterPerson: function(name) {
            // 適当なfilter処理
            if (name == "hogetaro") {
                return name;
            }
        }
    }
})
```
というようにする。
これでhogetaroと一致する名前データのみ出力される。

ちなみに、このfiltersプロパティにフィルタを定義することはVue1.xでもできました。

## 3. グローバルにfilterを定義する
前の例では、Viewインスタンス生成の中でfilterを定義していた。
そうではなく、グローバルにfilterを定義するこもできる。
これもVue1.xでも利用できました。

```js
Vue.filter('hoge-filter',  function(value) {
  // 適当なfilter処理
  if (value == 'hogetaro') {
      return value;
  }
});
```
これで、

```
{{ person.name | hoge-filter }}
```
としてフィルタを利用できます。


# 最後に
Vue1.xで利用できたbuilt-inフィルタはvue2.xでは利用できません。
computedプロパティを定義して代替として使います。

まだまだわからないことだらけなので、また勉強したいと思います。

***
参考にしたサイト
https://jp.vuejs.org/v2/guide/