Currently, I am incorporating the slider functionality in Vue using the Swiper framework. Although everything seems to be functioning properly, there is a minor issue that arises when filtering the data and completing the first cycle after scrolling. The filter correctly returns the desired items, but the initial rendered item is incorrect.
An interesting observation I made was that this discrepancy only occurs when sliding "down", while it works perfectly fine when sliding "up".
Upon further analysis, I suspect that the root of the problem lies in the updating process. Ideally, I would like to update the information before returning the filtered data in the getter function; however, I am unsure how to reference my swiper instance. It's essential to note that Vuex should not have explicit knowledge about frontend operations.
The following is my Vuex getter responsible for filtering the data (which consistently produces accurate results):
filterByCategory(state, getters, rootState) {
if (rootState.shared.selectedCategory !== 'All') {
return state.items.filter(
item => crypto.decrypt(item.category) === rootState.shared.selectedCategory,
);
}
return state.items.filter(item => item.title.toLowerCase().indexOf(getters.filters.searchString.toLowerCase()) >= 0);
},
To access my computed data using mapGetter, I employ the following syntax:
...mapGetters('data', ['filterByCategory']),
Below is the component responsible for rendering the slides (notably, the first product-slide appears incorrectly):
<swiper
ref="productSlider"
:options="swiperOptions"
class="product-slider"
@slideChange="onSlideChange"
>
<product-slide
v-for="item in items"
:key="item.id"
:item="item"
/>
<div
slot="pagination"
class="product-slider__pagination"
/>
</swiper>
Additionally, here are the functions within the data()
and methods used to update the swiper:
props: {
items: {
type: Array,
default: () => [],
required: true,
},
},
data() {
const self = this;
return {
swiperOptions: {
direction: 'vertical',
loopedSlides: 1,
spaceBetween: 30,
slidesPerView: 1,
effect: 'fade',
loop: true,
mousewheel: {
invert: false,
},
pagination: {
el: '.product-slider__pagination',
clickable: true,
dynamicBullets: true,
dynamicMainBullets: 1,
},
},
};
},
computed: {
swiper() {
return this.$refs.productSlider.swiper;
},
},
updated() {
if(this.swiper) {
this.swiper.update();
console.log('swiper-updated');
}
},
beforeDestroy() {
if(this.swiper) {
console.log('swiper-before-destroy');
this.swiper.destroy();
}
},
watch: {
items(newValue, oldValue) {
if (this.swiper) {
console.log(this.items);
this.$nextTick(() => {
this.swiper.update();
});
}
},
},
methods: {
onSlideChange() {
console.log('Slide did change');
},
}
I've exhausted all possible solutions but seem unable to pinpoint where the issue lies. Even enabling observer: true
has not resolved the matter. At this point, I'm uncertain whether the fault is mine or an inherent flaw within the framework. Any assistance would be greatly appreciated.
You can view a simple exemplar on CodePen.