swiperをずっと使ってたんですが、Nuxtで使う時に困ったところがあったので、
実装方法と一緒に、ハマりポイントについても書いていきます。
TypeScriptで書いてます。
前提条件
Nuxt.js v2.11.0
pug
TypeScript
で、説明していきます。
準備
yarn add vue-awesome-swiper
pulguinsの設定
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
というファイルを作って。
次のように書いたファイルを設置しておいてください。これで消えます。
declare module 'vue-awesome-swiper'
nuxt.config.tsにpuluginsの設定を追記します。
plugins: [
{ src: '~plugins/vue-awesome-swiper', ssr: false },
],
ここまでで準備完了です。
実装
components
まず、swiperだけのcomponentsを作ります。
例として、親componentsから画像のパスの配列を渡してsliderをつくようなコードで説明します。
<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の公式のドキュメントの書き方は
<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からは、特別なこともなく呼び出します。
<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>
おわり
おわり