问题描述
在 Vue 中使用 ajax 请求循环展示轮播图 分页器小圆点显示不全 轮播图滑动出错
解决方案
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/swiper@5.3.6/css/swiper.min.css"
/>
<div id="app">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="item in bannerList">
<img :src="item.url" alt="" />
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/swiper@5.3.6/js/swiper.min.js"></script>
1 可以在数据更新之后的 updated 中去做 swiper 的更新
swiper 自带一个实例方法 mySwiper.update(updateTranslate) mySwiper - new Swiper 时生成的 Swiper 的实例对象 update - 方法 updateTranslate - 可选参数,布尔值类型。默认为 false。当需要重新计算 swiper 容器的位移变化时需要为 true。
var vm = new Vue({
el: "#app",
data: {
bannerList: [],
},
created() {
$.ajax({
url: "banner.json",
type: "GET",
success: (res) => {
console.log(res);
this.bannerList = res;
},
});
},
mounted() {
this.mySwiper = new Swiper(".swiper-container", {
pagination: {
el: ".swiper-pagination",
dynamicBullets: true,
},
});
},
updated() {
this.mySwiper.update();
},
});
2 在数据更新之后使用 vm.$nextTick()实例方法的回调去做 swiper 的更新
vm.$nextTick(callback) 数据更新完成并且真实 DOM 也更新完成之后立刻执行回调
var vm = new Vue({
el: "#app",
data: {
bannerList: [],
},
created() {
$.ajax({
url: "/data/banner.json",
type: "GET",
success: (res) => {
console.log(res);
this.bannerList = res;
this.$nextTick(() => {
this.mySwiper.update();
});
},
});
},
mounted() {
this.mySwiper = new Swiper(".swiper-container", {
pagination: {
el: ".swiper-pagination",
dynamicBullets: true,
},
});
},
});
3 可以在数据更新之后使用 setTimeout 来做 swiper 的更新
var vm = new Vue({
el: "#app",
data: {
bannerList: [],
},
created() {
$.ajax({
url: "/data/banner.json",
type: "GET",
success: (res) => {
console.log(1);
console.log(res);
this.bannerList = res;
setTimeout(() => {
this.mySwiper.update();
});
},
});
},
mounted() {
console.log(2);
this.mySwiper = new Swiper(".swiper-container", {
loop: true,
pagination: {
el: ".swiper-pagination",
dynamicBullets: true,
},
});
},
});
4 推荐解决方案
var vm = new Vue({
el: "#app",
data: {
bannerList: [],
},
methods: {
getBannerList() {
$.ajax({
url: "/data/banner.json",
type: "GET",
success: (res) => {
this.bannerList = res;
this.$nextTick(() => {
this.initSwiper();
});
},
});
},
initSwiper() {
new Swiper(".swiper-container", {
loop: true,
pagination: {
el: ".swiper-pagination",
},
});
},
},
created() {
this.getBannerList();
},
});
三种方案的比较
首推vm.$nextTick(callback) 内置方法 setTimeout 不好控制 updated 生命周期钩子函数 任何数据的更新都会引起 swiper 的更新 容易损耗性能
轮播图循环问题
原因描述 loop 在 swiper 内部在初始化时会去做复制 DOM 的操作 等数据请求到并且真实的 DOM 更新之后再去做 new Swiper 的操作 可以参考 swiper 的Observer(监视器)
|