Swiper - 在第一次循环后第一个项目被错误呈现但数据是正确的
Swiper - after first cycle the first item is wrongly rendered but data is correct
我正在使用 Swiper 框架在 Vue 中获取滑块功能。一切正常,除了如果我过滤我的数据并且在滚动后第一个周期结束后它会显示错误的项目。过滤器 return 是正确的项目,但呈现的 第一个 项目是错误的。
我发现的是,只有滑动才会这样"down"。如果我滑动"up"。然后一切正常。
我认为问题在于更新。我想在 return getter 中的过滤数据之前更新它,但我不知道如何引用我的 swiper 实例?但是后来 vuex 的想法就消失了,因为 vuex 基本上应该对前端一无所知。
这是我的 vuex getter,它过滤我的数据(return 总是正确的数据):
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()
和更新刷卡器的方法:
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
将更新交给框架来处理。即使那样它也不起作用。我已经尝试了从 Google 中找到的所有内容,但没有任何效果。我想知道是我的问题还是框架的bug。非常感谢任何帮助。
我创建了简单的 CodePen 示例。
我终于从 this Github 问题中找到了问题的答案!
我所做的如下:
我在 data()
和方法 reRender()
中创建了 show
变量,其中包含以下内容:
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>
组件。
并且在 watcher 中我调用了 reRender()
函数。
我不确定它有多正确,但它现在可以正常工作了。
我正在使用 Swiper 框架在 Vue 中获取滑块功能。一切正常,除了如果我过滤我的数据并且在滚动后第一个周期结束后它会显示错误的项目。过滤器 return 是正确的项目,但呈现的 第一个 项目是错误的。
我发现的是,只有滑动才会这样"down"。如果我滑动"up"。然后一切正常。
我认为问题在于更新。我想在 return getter 中的过滤数据之前更新它,但我不知道如何引用我的 swiper 实例?但是后来 vuex 的想法就消失了,因为 vuex 基本上应该对前端一无所知。
这是我的 vuex getter,它过滤我的数据(return 总是正确的数据):
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()
和更新刷卡器的方法:
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
将更新交给框架来处理。即使那样它也不起作用。我已经尝试了从 Google 中找到的所有内容,但没有任何效果。我想知道是我的问题还是框架的bug。非常感谢任何帮助。
我创建了简单的 CodePen 示例。
我终于从 this Github 问题中找到了问题的答案!
我所做的如下:
我在 data()
和方法 reRender()
中创建了 show
变量,其中包含以下内容:
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>
组件。
并且在 watcher 中我调用了 reRender()
函数。
我不确定它有多正确,但它现在可以正常工作了。