我正在使用Swiper框架来获取Vue中的滑块功能。一切正常,但是如果我过滤我的数据并且在滚动后第一个周期结束后它显示我错误的项目。过滤器返回正确的项目,但渲染的第一个项目是错误的。
我发现的是,只有当我向下滑动时才会如此。如果我向上滑动。一切正常。
我认为问题在于更新。我想在getter中返回过滤后的数据之前更新它,但我不知道如何引用我的swiper实例?但是后来vuex的想法消失了,因为vuex基本上不应该对前端有任何了解。
这是我的vuex getter,可以过滤我的数据(总是返回正确的数据):
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);
},
我正在使用mapGetter来计算我的数据:...mapGetters('data', ['filterByCategory']),
这是渲染幻灯片的组件(第一个产品幻灯片被错误地渲染):
<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>
这些是我的data()
和更新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,
},
// autoHeight: true,
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');
},
}
我只是找不到我做错了什么。我还尝试使用observer: true
来更新框架来处理。即便如此,它也无法正常工作。我已经尝试了从谷歌找到的所有东西,但没有任何工作。我想知道它是我还是框架中的bug。任何帮助深表感谢。
我创建了简单的CodePen示例。
我终于从this Github问题找到了我的问题的答案!
我做的是以下:
我在show
和方法data()
中创建了reRender()
变量,其中包含以下内容:
reRender(){
this.show = false
this.$nextTick(() => {
//re-render start
this.show = true
this.swiper.destroy();
this.$nextTick(() => {
//re-render end
this.swiper.update();
})
})
}
我将:v-if="show"
添加到<swiper></swiper>
组件中。
在观察者中我称之为reRender()
功能。
我不确定它是多么正确,但它现在正在运作。