swiper模仿下滑无限轮播

效果图,添加:vertical="true"属性便可往下无限滑

技术栈:vue2、uniapp、微信小程序

解决了什么:无限渲染dom节点只挂载三个dom元素

代码块

<template>
    <view class="content">
        <view class="title">{{originIndex +1 }}/{{ originList.length }}</view>
        <swiper class="swiper" :circular="circularCom" :current="displayIndex" :vertical="true" @change="swiperChange"
            swiperDuration="250">
            <swiper-item v-for="(item, index) in displaySwiperList" :key="index">
                <view class="wrap_content">{{ item }} </view>
            </swiper-item>
        </swiper>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                originList: [], // 源数据
                displaySwiperList: [], // swiper需要的数据
                displayIndex: 0, // 用于显示swiper的真正的下标数值只有:0,1,2。
                originIndex: 0, // 记录源数据的下标
            };
        },
        computed: {
            circularCom() {
                // 第一条数据时,关闭无限轮询
                return this.originIndex === 0 ? false : true
                // return false
            }
        },
        methods: {
            /**
             * 初始一个显示的swiper数据
             * @originIndex  从源数据的哪个开始显示默认0,如从其他页面跳转进来,要显示第n个,这个参数就是他的下标
             */
            initSwiperData(originIndex = this.originIndex) {
                const originListLength = this.originList.length; // 源数据长度
                const displayIndex = this.displayIndex

                const displayList = [];
                const isFirstDisplayIndex = displayIndex == 0 // swiper滑块在第一个0,1,2
                const isLastDisplayIndex = displayIndex == 2 // swiper滑块在最后一个0,1,2
                const isFristOriginIndex = originIndex == 0 // 第一条数据源下标
                const isLastOriginIndex = originIndex == originListLength - 1 // 最后一条数据源下标

                const displayIndexNearUp = isFirstDisplayIndex ? 2 : displayIndex - 1 // 向上swiper滑块下标
                const displayIndexNearDown = isLastDisplayIndex ? 0 : displayIndex + 1 // 向下swiper滑块下标
                const originIndexNearUp = isFristOriginIndex ? originListLength - 1 : originIndex - 1 // 向上滑的数据源下标
                const originIndexNearDown = isLastOriginIndex ? 0 : originIndex + 1 // 向下滑的数据源下标

                displayList[displayIndex] = this.originList[originIndex];
                displayList[displayIndexNearUp] = this.originList[originIndexNearUp]
                displayList[displayIndexNearDown] = this.originList[originIndexNearDown]

                this.displaySwiperList = displayList;
            },
            /**
             * swiper滑动时候
             */
            swiperChange(event) {
                const {
                    current
                } = event.detail;
                const originListLength = this.originList.length; // 源数据长度
                const hasLastOriginIndex = this.originIndex == originListLength - 1 // 最后一条数据
                const hasFirstOriginIndex = this.originIndex == 0 // 第一条数据

                if ([-1, 2].includes(this.displayIndex - current)) {
                    /**
                     * =============向后/向下滑动=============
                     * 0(displayIndex)滑到1(current): -1
                     * 1(displayIndex)滑到2(current): -1
                     * 2(displayIndex)滑到0(current): 2
                     * */
                    this.originIndex = hasLastOriginIndex ? 0 : this.originIndex + 1;
                } else if ([-2, 1].includes(this.displayIndex - current)) {
                    /**
                     * =============向前/向上滑动=============
                     * 0(displayIndex)滑到2(current): -2
                     * 2(displayIndex)滑到1(current): 1
                     * 1(displayIndex)滑到0(current): 1
                     * */
                    this.originIndex = hasFirstOriginIndex ? originListLength - 1 : this.originIndex - 1;
                }

                this.displayIndex = current // 必须写在这,不能写在上面
                this.initSwiperData();
            },

        },
        created() {
            const tempList = []
            for (let i = 1; i <= 11; i++) {
                tempList.push(i);
            }
            if (tempList.length % 3 == 1) {
                const staticArr = [110, 120]
                tempList.push(...staticArr)
            } else if (tempList.length % 3 == 2) {
                const staticArr = [119]
                tempList.push(...staticArr)
            }
            this.originList = tempList
            this.initSwiperData();
        },
    };
</script>

<style>
    .title {
        width: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100rpx;
    }

    .swiper {
        height: calc(100vh - 100rpx);
    }

    .wrap_content {
        border-radius: 20rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        background: gray;
        height: 100vh;
        color: green;
        font-size: 80px;
        margin: 0rpx 40rpx;
    }
</style>

注意缺陷,一定要看

  1. 由于swiper自身的问题,动态设置circular无限轮询属性时 :circular="false",切换会丢失动画。这是swiper的一个缺陷,官方也知道但是一直没有修复。从1切换到2就能感受到,这是个用户体验的问题,参考网友踩坑记录https://developers.weixin.qq.com/community/develop/doc/000a2a8b4889484e31a61630653c00

  1. 数据长度必须是3的倍数,如果数据不够手动添加,我们可以添加静态数据比如一张图片或者背景div

  1. 只能在微信小程序端、H5页面运行,在客户端(安卓、IOS)十之八九是行不通

最后

在代码块里面都有些非常多注释,如果有疑惑,使用console.log挨个把变量值打印出来,应该马上就能理解。

这只是deom实例,swiper-item标签里面可以直接放video标签。demo主要解决问题是渲染dom元素,如果渲染所有数据,当数据达到100条左右就该头疼了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现 swiper-item 的自动轮,你可以使用 Swiper 组件的 autoplay 属性。在 Swiper 组件中,设置 autoplay 属性为 true,即可启用自动轮功能。默认情况下,Swiper 组件的自动轮间隔时间为 3000 毫秒(即 3 秒),你也可以通过设置 delay 属性来调整轮间隔时间。 下面是一个示例代码,演示了如何使用 Swiper 组件实现 swiper-item 的自动轮: ```html <template> <div> <swiper :autoplay="true" :delay="4000"> <swiper-slide v-for="(item, index) in items" :key="index"> <!-- swiper-item 的内容 --> <div class="swiper-item"> {{ item }} </div> </swiper-slide> </swiper> </div> </template> <script> import { Swiper, SwiperSlide } from 'swiper/vue'; import 'swiper/swiper-bundle.css'; export default { components: { Swiper, SwiperSlide, }, data() { return { items: ['item 1', 'item 2', 'item 3'], // swiper-item 的数据 }; }, }; </script> <style> .swiper-item { /* swiper-item 样式 */ } </style> ``` 上面的示例代码使用了 Vue.js 和 Swiper Vue 组件。你需要安装 `swiper` 和 `swiper/vue` 包,并按需引入 SwiperSwiperSlide 组件。另外,还需要在样式中引入 `swiper/swiper-bundle.css`。 在示例代码中,Swiper 组件包含了多个 SwiperSlide 组件,每个 SwiperSlide 组件对应一个 swiper-item。你可以通过在 `items` 数据中添加或删除元素来调整 swiper-item 的数量和内容。 值得注意的是,Swiper 组件还有许多其他的配置选项,你可以根据自己的需求进行调整,比如设置切换效果、分页器等。详细的配置选项可以参考 Swiper 官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值