栗子荔枝
栗子荔枝
  • 发布:2024-03-12 13:19
  • 更新:2024-03-13 17:36
  • 阅读:400

swiper 动态修改 circular 属性出现异常

分类:nvue

渲染3个 swiper-item 实现短视频效果。
mumu模拟器(APP):动态修改 circular 属性为 true 后 @change 事件会同时触发两次,然后 swiper无法继续向后滑动。

2024-03-12 13:19 负责人:无 分享
已邀请:
栗子荔枝

栗子荔枝 (作者) - 暂无介绍

还有个问题,在浏览器下向前返回第一个 swiper-item 修改 circular 属性为 false 时,会导致第一个和第三个 swiper-item 重叠在一起。

套马杆的套子

套马杆的套子 - 没有解决不了的问题,只有解决不完的问题

我刚试了下没能复现
可以贴下你的代码看看

  • 栗子荔枝 (作者)

    <script>

    let that;

    // import flvModeule from "../../components/flvModule/flvModule.vue";

    export default {

    // components: {

    // flvModeule

    // },

    data() {

    return {

    originList: [], // 源数据

    displaySwiperList: [], // swiper需要的数据

    displayIndex: 0, // 用于显示swiper的真正的下标数值只有:0,1,2。

    originIndex: 0, // 记录源数据的下标

    current: 0,

    isFirstLoad: true, //是否首次加载

    circular: false, //是否衔接滚动

    isData: true, //是否还有数据

    idxKey: null, //当前视频id


                windowWidth: 0,  
    windowHeight: 0,
    };
    },
    onLoad() {
    that = this;
    that.windowWidth = uni.getSystemInfoSync().windowWidth;
    that.windowHeight = uni.getSystemInfoSync().windowHeight;
    that.xhFun();
    },
    methods: {
    /**
    * 获取数据(模拟)
    */
    xhFun(type = false) {
    if (!type) {
    for (let i = 0; i < 10; i++) {
    let objs = {
    name: `海鲸遨游大海${i}`,
    series: 31,
    nowNum: 1,
    currentTime: 10,
    duration: 46.613333,
    isCollect: false,
    collect: 2193,
    isConcern: false,
    path: 'http://vjs.zencdn.net/v/oceans.mp4',
    // path: '/static/video/ceshi.mp4',
    coverImg: `/static/images/ceshi/img-ceshi-0.png`,
    id: i
    }
    that.originList.push(objs);
    }
    } else {
    // return that.isData = false; //请求无数据后,状态关闭
    let newData = [];
    for (let i = 0; i < 3; i++) {
    let objs = {
    name: `海鲸遨游大海${i}`,
    series: 31,
    nowNum: 1,
    currentTime: 0,
    duration: 46.613333,
    isCollect: true,
    collect: 2193,
    isConcern: true,
    path: 'http://vjs.zencdn.net/v/oceans.mp4',
    // path: '/static/video/ceshi.mp4',
    coverImg: `/static/images/ceshi/img-cs-${i}.png`,
    id: i
    }
    newData.push(objs);
    }
    that.originList = [...newData, ...that.originList];
    }
    if (that.isFirstLoad) {
    let timer = setTimeout(() => {
    that.initSwiperData();
    }, 300);
    }
    },

    /**
    * 初始一个显示的swiper数据
    * @originIndex 从源数据的哪个开始显示默认0,如从其他页面跳转进来,要显示第n个,这个参数就是他的下标
    */
    initSwiperData(originIndex = that.originIndex) {
    const originListLength = that.originList.length; // 源数据长度
    const displayList = [];
    that.id = that.originList[originIndex].id;
    displayList[that.displayIndex] = that.originList[originIndex];
    displayList[that.displayIndex + 1 == 3 ? 0 : that.displayIndex + 1] = that.originList[originIndex + 1 ==
    originListLength ? 0 : originIndex + 1];
    displayList[that.displayIndex - 1 == -1 ? 2 : that.displayIndex - 1] = that.originList[originIndex - 1 == -
    1 ? originListLength - 1 : originIndex - 1];
    that.displaySwiperList = displayList;
    // 加载更多
    let loadMoreOffsetCount = 2; //滚动加载阈值 (即播放到剩余多少个之后触发加载更多);
    let pCount = that.originList.length - loadMoreOffsetCount;
    if (originIndex == pCount) {
    console.log('继续加载');
    if (that.isData) that.xhFun(true); //还有数据继续加载
    if (!that.isData) that.circular = false; // 没有数据后关闭衔接
    }
    },

    /**
    * swiper滑动时候
    */
    swiperChange(e) {
    const current = e.detail.current;
    that.current = current;
    that.isFirstLoad = false;
    const originListLength = that.originList.length; //获取源数据长度
    // 向后滚动
    if (that.displayIndex - current == 2 || that.displayIndex - current == -1) {
    that.originIndex = that.originIndex + 1 == originListLength ? 0 : that.originIndex + 1;
    that.displayIndex = that.displayIndex + 1 == 3 ? 0 : that.displayIndex + 1;
    that.initSwiperData(that.originIndex);
    if (that.originIndex > 1 && that.isData) {
    that.circular = true;
    console.log('在这修修改circular属性后,又触发一次@change回调')
    }
    }
    // 如果两者的差为-2或者1则是向前滑动
    if (that.displayIndex - current == -2 || that.displayIndex - current == 1) {
    that.originIndex = that.originIndex - 1 == -1 ? originListLength - 1 : that.originIndex - 1;
    that.displayIndex = that.displayIndex - 1 == -1 ? 2 : that.displayIndex - 1;
    that.initSwiperData(that.originIndex);
    if (that.originIndex == 0 && current == 0) that.circular = false;
    }
    }

    }
    }

    </script>


    <template>

    <view>

    <swiper class="swiper-box" :style="'height:'+windowHeight+'px;'" :current="current" :circular="circular"

    @change="swiperChange" :vertical="true" duration="300">

    <swiper-item v-for="(item, index) in displaySwiperList" :key="item.id">

    <text style="color: #fff;font-size: 40px;">{{item.id}} , {{id}}</text>

    <!-- <block v-if="item.id === id">

    <flvModeule :item="item" :idxKey="id" :windowWidth="windowWidth" :windowHeight="windowHeight" />

    </block>

    <view :style="'width:'+windowWidth+'px;height:'+windowHeight+'px;'" v-else>

    <image :style="'width:'+windowWidth+'px;height:'+windowHeight+'px;'" :src="item.coverImg" />

    </view> -->

    </swiper-item>

    </swiper>

    </view>

    </template>


    <style lang="less">

    .swiper-box {

    background-color: #000;

    }

    </style>

    2024-03-12 13:58

  • 套马杆的套子

    回复 栗子荔枝: 我试了你的代码,在that.circular = true;后,没出现@change触发两次的情况啊,

    2024-03-12 14:21

  • 栗子荔枝 (作者)

    回复 套马杆的套子: 是nvue文件吗,然后使用mumu模拟器运行安卓基座

    2024-03-12 14:26

栗子荔枝

栗子荔枝 (作者) - 暂无介绍

问题找到了,只要 if (e.detail.source == 'autoplay') return; 就好了

要回复问题请先登录注册