一、现象
在使用Swiper轮播图时,图片正常轮播,但是分页器也就是下方显示页码小白点的却跟当前图片的顺序不相对应
二、分析
主要是因为在建立swiper对象时,未在数据请求结束后初始化swiper对象,若对象数据还在请求过程中,初始化swiper对象,会导致创建多个swiper对象,而小白点分页器的时间轴则是一条,多个时间点上创建的swiper对象会同时操纵这个分页器,导致分页器与轮播图不同步的现象
三、解决方法
1.需要在updated里面进行swiper对象的建立
2.使用Vue.nextTick() 或者 this.$nextTick()这个方法
作用:在下次 DOM 更新循环结束之后执行延迟回调。
解释:在修改数据之后立即使用这个方法,获取更新后的 DOM。
使用方法:
// 修改数据
vm.msg = 'Hello'
// DOM 还没有更新
Vue.nextTick(function () {
// DOM 更新了
})
// 作为一个 Promise 使用 (2.1.0 起新增,详见接下来的提示)
Vue.nextTick()
.then(function () {
// DOM 更新了
})
3.使用自定义指令创建一个v-swiper指令来操作dom(主要通过自定义指令的inserted来解决)
inserted 插入最后一个元素时初始化swiper
附下v-swiper创建代码
html部分
<div id="box">
<div class="swiper-container swipe">
<div class="swiper-wrapper">
<!--内部数据datalist发生变化了,然后生成3个swiper-slide真实dom,插入到swiper-wrapper里面去-->
<div
class="swiper-slide"
v-for="(data,index) in datalist"
v-swiper:swipe="{current:index,length:datalist.length,swipe:'swipe'}"
>
{{data}}
</div>
</div>
<!--分页器-->
<div class="swiper-pagination"></div>
</div>
</div>
自定义指令部分
<!--引入swiper or vue插件-->
<script src="./base/swiper.min.js"></script>
<script src="./base/vue.js"></script>
<script>
//有很多的插件,其实只能实例化一次,
//swiper实例化了多次之后,其实还是可以进行轮播效果,但是我们发现分页器效果已经失效了。
//需求:封装一个指令v-swiper,实现内部帮助我们实例化轮播图的功能
//问题:因为有三个swiper-slide的真实dom生成然后插入,所以new Swiper实例化了3次===>导致了分页器不管用了
//解决? 等最后一个元素插入完成后再去实例化不就ok了吗?怎么样是代表最后一个元素插入了
//那么获取到最后一个插入的元素的下标 === 传入的datalist的数组的长度-1
//自定义指令 v-swiper
Vue.directive("swiper",{
inserted(el,binding,vnode){
// 这个地方是通过vnode.context获取到vue实例,然后就可以通过这个实例.datalist.length获取到数组的长度了
// console.log(vnode.context.datalist.length)
//代表最后一个元素插入完毕了,再进进行一次实例化操作就可以了
if(binding.value.current === binding.value.length-1){
//如果外部 {current,length,swipe:'swipe'}
//new Swiper("."+binding.value.swipe,{.....})
new Swiper("."+binding.arg,{ //默认swiper执行3次,因为插入了3个swiper-slide的真实dom
loop:true,
pagination:{
el:".swiper-pagination"
}
})
}
}
})
new Vue({
el:"#box",
data:{
datalist:[] //定义了初始化的数据
},
// updated(){
// new Swiper(".swipe",{
// loop:true,
// pagination:{
// el:".swiper-pagination"
// }
// })
// },
created(){
setTimeout(() => {
this.datalist = ["111","222","333"] //更改数据
// this.$nextTick(()=>{
// new Swiper(".swipe",{
// loop:true,
// pagination:{
// el:".swiper-pagination"
// }
// })
// })
}, 3000);
}
})
</script>
</body>
</html>