Reputation: 353
As the title says, I'm trying to use swiperjs with Vue 2. I've used the API from swiper and another library "vue-awesome-swiper" to try and get it working. I get to the point with both approaches where everything appears functional but it's just the navigation buttons that aren't working and touch swiping is also disfuncitonal.
In each of the following approaches, I'm getting a seemingly perfect swiper but navigation is not working in either. I'm using vue 2.6 and swiper 6.7.
Here's what I have using vue-awesome-swiper:
<template>
<div>
<h2 class="swiper-container__title">{{ sliderHeading }}</h2>
<swiper :options="swiperOption" class="swiper">
<!-- Loops through item data and creates a carousel item -->
<div v-for="item in mediaItems" :key="item.id">
<swiper-slide>
<item :mediaItem="item"></item>
</swiper-slide>
</div>
<div class="swiper-button-prev" slot="button-prev"></div>
<div class="swiper-button-next" slot="button-next"></div>
</swiper>
<hr class="carousel-container__separator" />
</div>
</template>
<script>
import Item from "./Item.vue";
import { Swiper, SwiperSlide } from "vue-awesome-swiper";
import "swiper/swiper-bundle.min.css";
export default {
name: "swiper-example-pagination-progress",
title: "Progress pagination",
components: {
Item,
Swiper,
SwiperSlide
},
data() {
return {
swiperOption: {
slidesPerView: 7,
spaceBetween: 30,
loop: true,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
}
}
};
},
props: {
mediaItems: {
type: Array,
default: () => []
},
sliderHeading: String
}
};
</script>
And here I have the same results trying to use the swiper.js API myself:
<template>
<div class="carousel-container wow fadeIn" data-wow-duration="3s">
<div ref="slider" class="swiper-container">
<h2 class="swiper-container__title">{{ sliderHeading }}</h2>
<!-- Loops through item data and creates a carousel item -->
<div class="swiper-wrapper">
<div v-for="item in mediaItems" :key="item.id">
<item class="swiper-slide" :mediaItem="item"></item>
</div>
</div>
<div ref="nextEl" class="swiper-button-prev"></div>
<div ref="prevEl" class="swiper-button-next"></div>
</div>
<hr class="carousel-container__separator" />
</div>
</template>
<script>
import Item from "./Item.vue";
import Swiper from "swiper";
export default {
components: {
Item
},
props: {
mediaItems: {
type: Array,
default: () => []
},
sliderHeading: String
},
mounted() {
this.slider = new Swiper(this.$refs.slider, {
init: true,
slidesPerView: 7,
loop: true,
spaceBetween: 14,
observer: true,
breakpoints: {
1145: {
slidesPerView: 5
},
699: {
slidesPerView: 3
}
},
navigation: {
nextEl: this.$refs.nextEl,
prevEl: this.$refs.prevEl
}
});
},
computed: {},
methods: {},
data: function() {
return {
slider: null
};
}
};
</script>
Upvotes: 1
Views: 11065
Reputation: 138696
div
wrappervue-aweomse-swiper
expects swiper-slide
to be immediate descendants, so remove the div
wrapper; and move the v-for
and key
props to swiper-slide
:
<!-- BEFORE -->
<swiper>
<div v-for="item in mediaItems" :key="item.id">
<swiper-slide>
...
</swiper-slide>
</div>
</swiper>
<!-- AFTER -->
<swiper>
<swiper-slide v-for="item in mediaItems" :key="item.id">
...
</swiper-slide>
</swiper>
The slot syntax has changed in Vue 2.6.0, so slot="slotName"
is now v-slot:slotName
, and it must be applied to a <template>
:
<!-- BEFORE -->
<div class="swiper-button-prev" slot="button-prev"></div>
<div class="swiper-button-next" slot="button-next"></div>
<!-- AFTER -->
<template v-slot:button-prev>
<div class="swiper-button-prev"></div>
</template>
<template v-slot:button-next>
<div class="swiper-button-next"></div>
</template>
Your next/prev buttons have no click
-event handlers, so they do nothing. You could add a template ref to the vue-awesome-swiper
element, and get its swiperInstance
prop to get at the active swiper
instance. Then, use swiper.slideNext()
and swiper.slidePrev()
for the next and prev buttons, respectively.
<swiper ref="swiper">
<template v-slot:button-prev>
<div class="swiper-button-prev"
@click="$refs.swiper.swiperInstance.slidePrev()"></div>
</template>
<template v-slot:button-next>
<div class="swiper-button-next"
@click="$refs.swiper.swiperInstance.slideNext()"></div>
</template>
</swiper>
Upvotes: 3