1***@qq.com
1***@qq.com
  • 发布:2021-07-01 17:34
  • 更新:2021-12-13 18:02
  • 阅读:1327

swiper 修改current不能切换item

分类:uni-app

swiper 开启了circular,当滑动到列表第一个,再往前划动,跳回第一个

怎么设置都无效,current已绑定

有没有管理员或者大神给看看

2021-07-01 17:34 负责人:无 分享
已邀请:
DCloud_UNI_LXH

DCloud_UNI_LXH

提供完整示例看看

  • 1***@qq.com (作者)

    已上传完整代码

    2021-07-02 08:21

1***@qq.com

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>  
  • DCloud_UNI_LXH

    使用你的代码测试只切换swiperCurrent可以达到切换item的目的。

    2021-07-02 10:07

  • 1***@qq.com (作者)

    回复 DCloud_UNI_LXH: 直接赋值就可以吗。我这边测试不行呢。that.$data.swiperCurrent = lastIndex

    2021-07-02 14:24

  • 1***@qq.com (作者)

    回复 DCloud_UNI_LXH: 可以提供下您的代码吗

    2021-07-02 14:24

  • DCloud_UNI_LXH

    回复 1***@qq.com: 就用你的代码。你可以写一个简单的swiper排除一下其他影响

    2021-07-02 14:26

ofDamon

ofDamon

我也遇到了这个问题,请问你解决了吗?

2***@qq.com

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不生效,用这样解决的,的确可行

该问题目前已经被锁定, 无法添加新回复