Nuxt.jsでvue-awesome-swiperの使い方と注意

swiperをずっと使ってたんですが、Nuxtで使う時に困ったところがあったので、
実装方法と一緒に、ハマりポイントについても書いていきます。
TypeScriptで書いてます。

# 前提条件
Nuxt.js v2.11.0 
pug
TypeScript

で、説明していきます。

# 準備
```
yarn add vue-awesome-swiper
```
## pulguinsの設定
vue-awesome-swiper.tsを追加

```javascript:plugins/vue-awesome-swiper.ts
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'

Vue.use(VueAwesomeSwiper)
```
ここで、TypeScriptで書いている場合、多分`import VueAwesomeSwiper from 'vue-awesome-swiper'`でエラーが出ます。
なので、`@types/vue-awesome-swiper.d.ts`というファイルを作って。
次のように書いたファイルを設置しておいてください。これで消えます。

```javascript:@types/vue-awesome-swiper.d.ts
declare module 'vue-awesome-swiper'

```

nuxt.config.tsにpuluginsの設定を追記します。

```javascript:nuxt.config.ts

  plugins: [
    { src: '~plugins/vue-awesome-swiper', ssr: false },
  ],

```
ここまでで準備完了です。

# 実装
## components
まず、swiperだけのcomponentsを作ります。
例として、親componentsから画像のパスの配列を渡してsliderをつくようなコードで説明します。

```vuejs:components/swiper.vue

<template lang="pug">
  div
    swiper(:options="swiperOption" ref="swiper")
      swiper-slide(
        v-if='Array.isArray(images)'
        v-for='(image,key,index) in images'
        :key='index'
        )
        img(:src='image')
      .swiper-button-prev(ref='swiperButtonPrev',slot='button-prev')
        img(src='~/assets/images/arrow_prev.png')
      .swiper-button-next(ref='swiperButtonNext',slot='button-next')
        img(src='~/assets/images/arrow_next.png')
</template>

<script lang="ts">
import { Component, Vue, Prop, Provide } from 'nuxt-property-decorator'
import 'swiper/dist/css/swiper.css'

@Component({})
export default class SliderCommon extends Vue {
  $refs!: {
    swiper: any
    swiperButtonPrev: any
    swiperButtonNext: any
  }
  @Prop()
  images: any

  @Provide() swiperOption: any = {
    init: false
  }
  mounted() {
    this.$refs.swiper.swiper.params.spaceBetween = 10
    this.$refs.swiper.swiper.params.autoHeight = true
    this.$refs.swiper.swiper.params.navigation.nextEl = this.$refs.swiperButtonNext
    this.$refs.swiper.swiper.params.navigation.prevEl = this.$refs.swiperButtonPrev
    this.$refs.swiper.swiper.init()
  }
}
</script>

<style scoped lang="scss">
.swiper-button-next,
.swiper-button-prev {
  img {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
  }
}
</style>
```
この書き方で注意して欲しい点ですが、

- swiperOptionで、`init:false` にしている。
- swiper-button-prevとnext にそれぞれrefを設定している。
- mountedでSwiperのオプションを設定している。

です


vue-awesome-swiperの公式のドキュメントの書き方は

```vuejs
<script>
  swiperOption: any = {
    spaceBetween:10,
    autoHeight:true,
    navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev'
    }
  }
</script>
```
こんな感じで、data()で記述してtemplateで使っています。
静的サイトで、swiperを一つだけ、とか数が固定されているならそれぞれクラス変えるなどで対応できるんですが、
動的なサイトや、今後再利用する場合を考えると、
`init:false`で勝手に初期化されないようにして、
mountedでオプションを設定すると、refの値が取れるのでcomponents内のprev、nextをrefで設定が可能になって便利じゃないかと思ってこのようにしています。

親componentからは、特別なこともなく呼び出します。

```vuejs:index.vue
<template lang="pug">
div
    Swiper(:images='images')
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import Swiper from '~/components/swiper.vue'

@Component({
  components: {
    Swiper
  }
})
export default class Index extends Vue {
  get images() {
    return ['hoge.png','fuga.png']
  }
}
</script>

<style scoped lang="scss"></style>

```

# おわり
おわり