Nuxt.jsでVue用スライダーライブラリ Hooperを導入

# 導入の経緯

これまで弊社のRuby on Railsで製作されたプロダクトではスライダーライブラリとして`swiper.js`を用いており、新しくnuxt.jsで製作したものでも流れでswiperをvue向けに扱えるようにした`vue-awesome-swiper`を用いてきました。しかし、最近になってページスピードを詰めていくとvue-awesome-swiperにはいくつも欠点が見つかりました。

- Globallyにしかswiperをimportすることができない
- SSRに対応していない
- ファイルサイズが大きい
- やりたいことによってはbackground-imageで画像を表示するしかなく画像のlazyloadingなどができない

これらの問題を受け、当初はvue-awesome-swiperをいじって解決することや、生のswiperに書き換えることを考えましたが、少し探してみたらvue向けに作られた`Hooper`という優秀なライブラリを発見したため、こちらに鞍替えすることにしました。そこで導入手順などを簡単に記載します。

# Hooperの何がいいか

- 単なるComponentとしてimportすればすぐに使えて導入が非常に簡単
- SSR対応
- swiper.jsよりもかなりファイルサイズが小さい
- infinite loop, thumbnail pagination, responsive designなど様々なカスタマイズが可能

vueでよく用いられるスライダーライブラリとして他に`vue-carousel`がありましたが、そちらはinfinite loopが実現できなかったため今回は採用を見送りました。

# Hooperの欠点

- 新しすぎて情報が少ない

GitHubを見る限り公開されてから一年も経っていないようです。これから導入事例と共に情報が増えていくことを期待しています。

- swiperほどたくさんの機能を備えていない

今回実現したいことを実装するのには充分な機能を備えていましたが、超リッチなスライダーを作りたいときにはswiperの方がやれることは多いです。しかし発火するイベントを拾ってきて独自の動きを作ればある程度はHooperで対応できると思います。

# Hooper導入方法

今回はNuxt.jsのプロジェクトに導入しましたがvueで動いていれば同様の方法でどんなプロジェクトにも導入できるはずです。

## package.jsonにHooperを追加、インストール

`yarn add`でも`npm install`でもなんでもいいです

```json
"dependencies": {
  "hooper": "^0.3.4"
}
```

## Vue Component内でimportする

```vue
<script>
import { Hooper, 
         Slide,
         Pagination as HooperPagination, // ページネーションが必要なときにimport
         Navigation as HooperNavigation  // 左右のナビゲーションが必要なときにimport
        } from 'hooper'
import 'hooper/dist/hooper.css' // hooperのcssを適用
export default {
  components: {
    Hooper,
    Slide,
    HooperPagination,
    HooperNavigation
  }
}
</script>
```

これだけで準備が整います。

# 使用方法

[公式の実装例](https://baianat.github.io/hooper/examples.html#default-example)に様々なスライダーの例が掲載されています。

```vue
<template>
  <hooper>
    <slide>
      slide 1
    </slide>
    <slide>
      slide 2
    </slide>
    <slide>
      slide 3
    </slide>
    <slide>
      slide 4
    </slide>
    <slide>
      slide 5
    </slide>
    <slide>
      slide 6
    </slide>
    <hooper-pagination slot="hooper-addons"></hooper-pagination>
  </hooper>
</template>
```
[![Image from Gyazo](https://i.gyazo.com/8f80393e02e3fab86718c64d00640565.gif)](https://gyazo.com/8f80393e02e3fab86718c64d00640565)

# 設定

スライドスピードやページごとに表示する要素の個数を変更したい場合には`hooper`Componentにそれぞれのoptionのpropsを渡すか、`settings`にオプションをまとめたobjectを渡します

```vue
<template>
  <hooper :settings="hooperSettings"></hooper>
  または
　<hooper :items-to-show="1" :center-mode="true"></hooper>
</template>

<script>
export default {
  // 省略
  data() {
    return {
      hooperSettings: { 
        itemsToShow: 1, // 1ページに表示したい要素の個数
        centerMode: true, // 現在の要素を中央に表示するか
        breakpoints: { // breakpointを用いたいときはsettingsでまとめないとうまく渡せない
          480: {
            itemsToShow: 1.75 // 小数点以下の値も指定できる
          },
          640: {
            itemsToShow: 2.3
          }
        }
      }
    }
  }
}
</script>
```

設定について詳しく知りたい場合は[公式のAPIガイド](https://baianat.github.io/hooper/api.html)をご覧ください

# swiperからの移行で少し詰まったところ breakpoint指定

上記の例でbreakpointを指定してwidthごとにoptionを切り替えましたが、この時の指定方法がswiperと違って少し戸惑いました。

hooperでは上記のように指定すると幅が

- 0~480px => 1要素
- 480~640px => 1.75要素
- 640px~ => 2.3要素

のようにoptionが切り替わります。swiperとは真逆の指定方法なので最初少し詰まりました。

# まとめ

Hooperの導入方法と使用例を簡単にですがご紹介しました。最近ページスピードをかなり重視するようになってきているので、このような軽量で扱いやすいライブラリは非常におすすめできると思います。

# 参考
Hooper 公式 https://baianat.github.io/hooper/