记录使用vue中踩到的坑(1):在vue中使用swiper.js插件的js部分初始化时机问题
首先是原本代码:
export default {
data(){
return{
...
// 储存轮播图图片地址
topCarousel: [],
...
}
},
async mounted(){
try {
tmpTopCarousel = (
await this._axios({
method: "get",
url: "/api/goods",
params: {
page: 1,
limit: 9,
classify_id: 423,
project_id: 201,
},
})
).data.result.rows;
tmpTopCarousel.forEach((item) => {
this.topCarousel.push({
id: item.id,
picUrl: item.s_goods_photos[0].path,
thumbUrl: item.s_goods_photos[1].path,
gameName: item.name,
gameBh1: `${item.desc.split(",")[0]}`,
gameBh2: `${item.desc.split(",")[1]}`,
});
});
// 轮播图初始化
this.initTopSwiper();
} catch (err) {
console(err);
}
},
methods:{
initTopSwiper() {
// 顶部轮播图大图
this.topSwiper = new Swiper(".topSwiperBox", {
effect: "fade",
speed: 350,
fadeEffect: {
crossFade: true,
},
loop: true,
observer: true,
observeParents: true,
loopAdditionalSlides: 1,
// preventClicks: true,
});
// 顶部logo轮播
this.thumbSwiper = new Swiper(".thumbSwiperBox", {
speed: 350,
slidesPerView: 1,
loopAdditionalSlides: 1,
loop: true,
observer: true,
observeParents: true,
slideToClickedSlide: true,
centeredSlides: true,
spaceBetween: 40,
// 前进后退按钮
navigation: {
nextEl: ".thumb-button-next",
prevEl: ".thumb-button-prev",
},
});
// 双向控制
this.topSwiper.controller.control = this.thumbSwiper;
this.thumbSwiper.controller.control = this.topSwiper;
},
}
(这里省掉了html的布局部分)
这段代码在我的项目运行中并未报错,图片也都渲染了,从逻辑上似乎也没问题,先从后台拿到数据,再去初始化轮播图,但最后的结果却是轮播图里的loop:true
完全无效,以及一些其他bug。后来知道了是时机问题,在mounted
生命周期中,虚拟、实际dom都已渲染完毕,尽管await
让获取后台数据成为了同步操作,但是将更新后的topCarousel
渲染到dom中也就是更新dom仍然是异步的,相当于先对轮播图初始化,再把图片渲染上去。如何解决?只需做些许改动即可,代码如下:
// 顶部轮播图初始化;
this.$nextTick(() => {
this.initTopSwiper();
});
就是用vue提供的nextTick
去包裹轮播图初始化代码,这个api是在在下次 DOM 更新循环结束之后执行延迟回调。以下是参考网址:
https://cn.vuejs.org/v2/api/