swiper 开启了circular,当滑动到列表第一个,再往前划动,跳回第一个
怎么设置都无效,current已绑定
有没有管理员或者大神给看看
1***@qq.com (作者)
<template>
<view>
{{ swiperCurrent }}
<swiper :style="'height:' + swiperHeight + 'px;'" :duration="swiperDuration" :current="swiperCurrent" @change="swiperChange" circular>
<swiper-item v-for="(item, index) in swiperList" :key="index">
<item-view :item="item" :swiperHeight="swiperHeight"></item-view>
</swiper-item>
</swiper>
</view>
</template>
<script>
const START = 0;
const END = 2;
const SWIPER_LENGTH = 3;
const NO_PREV_PAGE = -1;
const NO_NEXT_PAGE = -2;
import itemView from "./item/item-index";
export default {
data() {
return {
// 滑动到的位置
swiperIndex: 0,
// 此值控制swiper的位置
swiperCurrent: 0,
// 当前swiper渲染的items
swiperList: [],
swiperChangeItem: ""
};
},
components: {
itemView
},
props: {
swiperHeight: {
type: Number,
default: 0
},
list: {
type: Array,
default: []
},
current: {
type: Number,
default: 0
},
// 值为0禁止切换动画
swiperDuration: {
type: String,
default: "250"
},
// 分页需要传此数据
total: {
type: Number,
default: 0
}
},
watch: {
'current': function(index) {
let that = this;
let current = index % SWIPER_LENGTH;
let { swiperIndex, swiperList } = that;
if (swiperList.length == 0 || swiperList[current] == null) {
return;
} // 如果change后还是之前的那一个item,直接return
if (current == swiperIndex && swiperList[swiperIndex].index == index) {
return;
}
that.init(index); // 如果change之后还是当前的current,比如之前是1、点击后是4 之前是2、点击后是5之类
// 那么不会走swiperChange的change方法,需要我们手动去给它加一个current,然后传出去
if (current == swiperIndex) {
that.$emit("change", {
detail: {
source: "",
current: index
}
});
}
}
},
methods: {
init(defaulaIndex) {
let that = this;
let list = that.list;
if (list == null || list.length == 0) {
return;
}
// 默认显示的index
let current = defaulaIndex % SWIPER_LENGTH;
that.$data.swiperList = that.getInitSwiperList(list, defaulaIndex);
that.$data.swiperIndex = current;
that.$data.swiperCurrent = current;
for (let i in that.$data.swiperList) {
Vue.set(that.$data.swiperList, i, that.$data.swiperList[i])
}
},
clear() {
this.$data.list = [],
this.$data.swiperList = []
},
swiperChange: function(e) {
let that = this;
let current = e.detail.current;
let lastIndex = that.swiperIndex;
let currentItem = that.$data.swiperList[current];
let info = {};
info.source = e.detail.source;
// 是正向衔接
let isLoopPositive = current == START && lastIndex == END;
if (current - lastIndex == 1 || isLoopPositive) {
// 如果是滑到了左边界或者下一个还未有值,弹回去
if (currentItem == null) {
info.current = NO_NEXT_PAGE;
that.$emit("change", {
detail: info
});
that.$data.swiperCurrent = lastIndex
Vue.set(that.$data, swiperCurrent, lastIndex)
return;
}
that.$data.swiperList[that.getNextSwiperChangeIndex(current)] = that.getNextSwiperNeedItem(currentItem, that.list)
}
// 反向滑动,到上一个的时候
// 是反向衔接
var isLoopNegative = current == END && lastIndex == START;
if (lastIndex - current == 1 || isLoopNegative) {
// 如果滑到了右边界或者上一个还未有值,弹回去
if (currentItem == null) {
info.current = NO_PREV_PAGE;
that.$emit("change", {
detail: info
});
setTimeout(function () {
that.$data.swiperCurrent = lastIndex
Vue.set(that.$data, 'swiperCurrent', lastIndex)
}, 0)
return;
}
that.$data.swiperList[that.getLastSwiperChangeIndex(current)] = that.getLastSwiperNeedItem(currentItem, that.list)
}
if (currentItem == null) return;
info.current = currentItem.index;
that.$emit("change", {
detail: info
}); // 记录滑过来的位置,此值对于下一次滑动的计算很重要
that.swiperIndex = current;
that.$data.swiperList = that.$data.swiperList
for (let i in that.$data.swiperList) {
Vue.set(that.$data.swiperList, i, that.$data.swiperList[i])
}
},
/**
* 获取初始化的swiperList
*/
getInitSwiperList: function(list, defaultIndex) {
let that = this;
let current = defaultIndex % SWIPER_LENGTH;
let realIndex = list.findIndex(function(item) {
return item.index == defaultIndex;
});
let currentItem = list[realIndex];
let swiperList = [];
swiperList[current] = currentItem;
swiperList[that.getLastSwiperChangeIndex(current)] = that.getLastSwiperNeedItem(currentItem, list);
swiperList[that.getNextSwiperChangeIndex(current)] = that.getNextSwiperNeedItem(currentItem, list);
// console.log("初始化swiperList",swiperList)
return swiperList;
},
/**
* 获取swiperList中current上一个的index
*/
getLastSwiperChangeIndex: function(current) {
return current > START ? current - 1 : END;
},
/**
* 获取swiperLit中current下一个的index
*/
getNextSwiperChangeIndex: function(current) {
return current < END ? current + 1 : START;
},
/**
* 获取上一个要替换的list中的item
*/
getLastSwiperNeedItem: function(currentItem, list) {
if (currentItem == null) return null;
let listNeedIndex = currentItem.index - 1;
let realIndex = list.findIndex(function(item) {
return item.index == listNeedIndex;
});
if (realIndex == -1) return null;
let item = listNeedIndex == -1 ? null : list[realIndex];
return item;
},
/**
* 获取下一个要替换的list中的item
*/
getNextSwiperNeedItem: function(currentItem, list) {
if (currentItem == null) return null;
let listNeedIndex = currentItem.index + 1;
let realIndex = list.findIndex(function(item) {
return item.index == listNeedIndex;
});
if (realIndex == -1) return null;
let total = this.total != 0 ? this.total : list.length;
let item = listNeedIndex == total ? null : list[realIndex];
return item;
}
}
};
</script>
<style>
/* components/swiper-limited-load/index.wxss */
</style>
1***@qq.com (作者)
回复 DCloud_UNI_LXH: 直接赋值就可以吗。我这边测试不行呢。that.$data.swiperCurrent = lastIndex
2021-07-02 14:24
2***@qq.com - jianshu.com/u/b7d77a496c1b
可能2个原因:
1 swiper动态变化时,dom还没更新,直接赋值了,换在nextTick中写
2 官方文档的【组件属性设置不生效解决办法】
this.swiperIndex=0 // 参考2必须先设置一次 (重要1)
if (this.curIndex == this.allQue.length - 1) { // 忽略 业务代码,siwper长列表优化上中下最后一个禁止右滑之类
this.$nextTick(()=>{ (重要2)
this.swiperIndex = 2;
})
}
// 配合重要1 重要2 ,可以去观察swper上的current的确改变了
之前存在修改current不生效,用这样解决的,的确可行
1***@qq.com (作者)
已上传完整代码
2021-07-02 08:21