セレクトボックスライブラリ「Vue-multiselect」のカスタマイズ方法

# 概要
Vue-multiselectはセレクトボックスを簡単に実装できる便利なVueライブラリです。
複数選択や自動補完など一般的にセレクトボックスに求められる機能はほぼ全て実現できます。
ここでは[公式サイト](https://vue-multiselect.js.org/#examples)を元にVue-multiselectのカスタマイズ方法の一部を紹介します。


# 基本の使い方
![スクリーンショット 2020-11-27 4.33.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677774/0157fbbf-ef77-e896-1df3-2778239a877f.png)

上図のようにシンプルな単一選択のセレクトボックスは以下のコードで実装できます。
なおCDNを利用するとVue-multiselectを簡単に試せます。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="shi-ma" data-slug-hash="RwGwBaO" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="RwGwBaO">
  <span>See the Pen <a href="https://codepen.io/shi-ma/pen/RwGwBaO">
  RwGwBaO</a> by shi-ma (<a href="https://codepen.io/shi-ma">@shi-ma</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

`options`プロパティには選択肢に設定したい配列を指定します。

`custom-label`プロパティに関数を指定すると、その返り値が選択肢として表示されるラベルとなります。
`options`が連想配列で各キーのバリューを組み合わせたラベルを作りたい時などは非常に便利です。
一つのキーのバリューのみをラベルとして表示したいときは、代わりに`label`プロパティを使い`label=country`というような書き方ができます。

`custom-label`や`label`は必須プロパティではありませんが、`options`が単なる配列でなく、連想配列の場合は設定しないと要素がそのまま表示されてしまいます。

![スクリーンショット 2020-11-27 4.03.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677774/af8f860a-1af6-6f91-57c6-550d50a5ec7e.png)


# Events
Vue-multiselectにはイベントプロパティが用意されており、ユーザーの操作をトリガーにして関数を実行することが可能です。

## イベントプロパティ一覧
| プロパティ名 | トリガー |
| -------- | -------- |
| `@input` | this.valueの値が変わる |
| `@select` | 選択肢を選ぶ | 
| `@remove` | 複数選択の時に選択を取り消す |
| `@search-change` | 検索クエリが変更される | 
| `@tag` | タグが追加される |
| `@open` | ドロップダウンが開かれる  | 
| `@close` | ドロップダウンが閉じられる  |

### @removeの利用例

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="shi-ma" data-slug-hash="xxExJLa" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Untitled2">
  <span>See the Pen <a href="https://codepen.io/shi-ma/pen/xxExJLa">
  Untitled2</a> by shi-ma (<a href="https://codepen.io/shi-ma">@shi-ma</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


例えば複数選択をオン（`multiple="true"`）にして`@remove`プロパティを上記のように設定すると、選択を取り消した時にアラートが表示されます。

![ezgif-3-08752ffc97a4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677774/7b104859-5b22-0516-e6a4-8f20b2e829c0.gif)




# 自動補完
Vue-multiselectはデフォルトで自動補完機能がオンになっており、オフにしたい時は`searchable`プロパティを`false`にします。
この自動補完は`label`プロパティの値（`custom-label`プロパティを指定していればその値）を元に候補を絞っています。

もし独自の検索条件を設定したい場合はカスタマイズできます。

### カスタマイズ例
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="shi-ma" data-slug-hash="VwKwBMN" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="VwKwBMN">
  <span>See the Pen <a href="https://codepen.io/shi-ma/pen/VwKwBMN">
  VwKwBMN</a> by shi-ma (<a href="https://codepen.io/shi-ma">@shi-ma</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

  `internal-search`プロパティを`false`にするとVue-multiselectの内部検索エンジンがオフになり、`options`を自由に設定できるようになります。

`@search-change`に指定した関数は検索クエリに変更がある度に実行され、さらに関数の第一引数には検索クエリが入ります。これを利用し、`options`をフィルタリングするような関数を書けば、検索クエリが変わる度に`options`が更新されるようになり、自動補完機能を代替できます。

![ezgif-1-51043d6a0877.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677774/5e3b79ee-17a4-bbbf-c168-92cd86d72126.gif)

# 終わりに
Vue-multiselectは用途に合わせてカスタマイズできる余地が大きいライブラリです。
ここでは現時点で日本語での説明が比較的少ない機能を紹介しましたが、Vue-multiselectには面白いカスタマイズ方法がまだまだあります。
Vueでセレクトボックスを実装するときはぜひVue-multiselectをお試しください。