r-swiper2 极致丝滑的 Vue2轮播组件

r-swiper2 vue2版本 含有禁止滑动块、快速连播模式,完美解决移动/PC端轮播需求

image.png

r-swiper2 这是一个vue2版本的轮播插件, 移动端和pc端都已完美适配

r-swiper 极致丝滑的 Vue3 轮播组件_悦动燃爆的博客-CSDN博客 已于2023/08/13上线

可能有小伙伴会问了,都2023年了,市面上的轮播组件数不胜数,谁还会傻到造轮播的轮子啊?

啊这。。。

不是说存在即合理吗

原因吗,主要有两点

1、如果引入官方swiper包会不会太大了,有必要吗?

2、有其他体积小的vue3开源组件,大部分场景都能适配,也多次遇到过特殊需求,无奈只能多次更改源码

But Please: Don't Repeat Yourself!

既然如此,那我就来封装一个功能强大,动效精美的轮播组件,可以完美适配绝大部分正常的业务需求(如果我这个组件还满足不了你的需求,本着忍一时越想越气,退一步越想越亏的原则,我劝你即刻去找产品对线。。。啊不,即刻联系我,我看看能不能再优化一下)。

此插件含有 禁止滑动块模式(noMove属性) 可以在swiper轮播内部实现阻拦滑动效果
丝滑模式(fast属性), 连续切换时, 没有强制限制动画时间, 切换快慢只取决于你的手速, 德芙~纵享丝滑
可嵌套使用, 目前遇到的所有bug都已更改

第一次写轮播还是17年,用的jQuery, 代码已经找不到了, 这次浏览了多个swiper开源代码,综合整理,做了部分优化,如果感觉不流畅或者对此插件有修改建议请及时联系我(联系方式在最底部), 最后希望大家能够喜欢!

安装依赖
  1. 打开项目根目录,执行命令
    // 如果使用的是npm
    npm i r-swiper2
    
    // 如果使用的是yarn
    yarn add r-swiper2
    

引入依赖

安装依赖后根据自己的需求引入

  • 全局引入

    import Swiper from 'r-swiper2'
    // ...
    Vue.use(Swiper)

  • 局部引入

    import {rSwiper, rSlide} from 'r-swiper2'
    
    export default {
      components: {
        'r-swiper': rSwiper,
        'r-slide': rSlide
      }
    }

组件讲解
名称介绍
rSwiper外部组件,各种事件动效都在此内完成
rSlide内部组件,包裹各个轮播页面内容

props参数 (一律使用小驼峰命名)
名称默认值类型介绍
fastfalseBoolean是否为快速滑动,纵享丝滑模式
autoPlayfalseBoolean是否自动轮播播放
playTime5000Number,Sting自动播放切换时间
speed500Number, String切换页面后的动画过渡时间
therehold100Number滑动多少距离后触发切页函数
slide0Number初始默认下标
indicatortrueBoolean指示器显示? 底部居中闪烁点/条状
indicatorFlashtrueBoolean指示器闪烁动效
noMovecsString非滑动模式 className(一会重点讲)
mobilefalseBoolean是否为移动端(移动端会隐藏 左右切页按钮)
vLockfalseBoolean垂直方向是否可滚动

methos事件
类型名称介绍
ref事件refDom.prev()切换到上一页
/refDom.next()切换到下一页
/refDom.slideTo(i)切换到指定下标(i)页
emit事件@loadEnd初次渲染完成后反馈函数
/@transitionend(i)切换页面后反馈函数, i 为当前下标

代码案例

<template>
<div class="home-style">
  <r-swiper class="swiper" ref="swiper" @loadEnd="funLoadEnd" @transitionend=funTransitionend>
    <r-slide>
      <img src="../3.png" alt="">
    </r-slide>
    <r-slide>
      <img src="../3.png" alt="">
    </r-slide>
    <r-slide>
      <img src="../3.png" alt="">
    </r-slide>
  </r-swiper>
</div>
</template>

<script>
import { rSwiper, rSlide } from 'r-swiper2'

export default {
  data() {
    return {
      nowIndex: 0 // 当前下标
    }
  },

  components: {
    'r-swiper': rSwiper, // 轮播外部组件
    'r-slide': rSlide // 轮播内部组件
  },

  computed: {
    // 当前swipe DOM
    swiperRef() {
      return this.$refs.swiper
    }
  },

  methods: {
    /**
    * 初始化加载完成反馈函数 2023-07-29 10:53:04 Ywr
    */
    funLoadEnd() {
      console.log('初始化加载完成')
    },
    /**
    * 切换页面完成反馈函数 2023-07-29 10:53:04 Ywr
    * @param {Number} i 当前下标
    */
    funTransitionend(i) {
      this.nowIndex = i
      console.log('当前下标', this.nowIndex)
    },

    /**
    * 切换页函数  2023-07-29 10:53:04 Ywr
    * @param {Number} i 下标
    * @param {Boolean} st 当前下标
    */
    changePage(i, st = false) {
      // 如果是跳转到某页
      if (st) {
        this.swiperRef.slideTo(i)
      }
      else {
        i < 0 ? (this.swiperRef.prev()) : (this.swiperRef.next())
      }
    }
  }
}
</script>

<style scope lang="scss">
.home-style {
  width: 100vw;
  height: 100vh;
  img {
    height: 100%;
  }
}
</style>

效果图

pc端

image.png


移动端

image.png

温馨提示

默认会显示底部指示器、 [pc端:左右两个切换按钮], 指示器和按钮都有点击切页效果

可根据props传值隐藏

具名插槽:
如果感觉 左右按钮、指示器样式不美观 或者想写入新内容 可使用以下插槽

  <!-- 左右按钮 切换上下页 -->
  <slot name="leftBtn">
  <slot name="rightBtn">

  <!-- 指示器 -->
  <slot name="indicator"></slot>

  <!-- 其他插槽 -->
  <slot name="all"></slot>

noMove讲解

为什么会有noMove属性 [默认为:cs] 呢?

如果我想两个轮播嵌套,子轮播切换时不影响父轮播,此时,就要求子轮播在滑动时不得触发父轮播滑动

pc端:

1、滑动顶部蓝色hello world!区域,会切换整体父swiper页面,如下效果

image.png

2、滑动地球图片,只切换内部的子swiper

微信图片_20230731114908.png

我们只需要给 内部的元素添加className属性 "cs" 即可

 <img class="cs" src="../2.png" alt="">

注意如果觉得 cs不符合要求,可以选择更改props属性

<r-swiper :noMove="yourClassName"></r-swiper>

<img class="yourClassName" src="../2.png" alt="">

完整代码案例

<template>
<div class="home-style">
  <r-swiper class="swiper" :autoPlay="false" ref="swiper" @loadEnd="funLoadEnd" @transitionend=funTransitionend :mobile="true">
    <r-slide>
      <div class="first-cont">
        <div class="can">hello world!</div>
        <!-- 注意此处 子swiper 的 noMove 属性一定不能是 cs [父swiper中的 noMove属性,否则自己的滑动事件也会被组织] -->
        <r-swiper class="child" noMove="nononononono" :mobile="true" :autoplay="false">
          <r-slide>
            <img class="cs" src="../2.png" alt="">
          </r-slide>
          <r-slide>
            <img class="cs" src="../2.png" alt="">
          </r-slide>
          <r-slide>
            <img class="cs" src="../2.png" alt="">
          </r-slide>
        </r-swiper>
      </div>
     </r-slide>
     <r-slide>
       <img src="../1.png" alt="">
     </r-slide>
     <r-slide>
      <img src="../1.png" alt="">
     </r-slide>
   </r-swiper>
</div>
</template>

<script>
import { rSwiper, rSlide } from 'r-swiper2'

export default {
  data() {
    return {
      nowIndex: 0 // 当前下标
    }
  },

  components: {
    'r-swiper': rSwiper, // 外部组件
    'r-slide': rSlide // 内部组件
  },

  computed: {
    swiperRef() {
      return this.$refs.swiper
    }
  },

  methods: {
    /**
    * 初始化加载完成 2023-07-29 10:53:04 Ywr
    */
    funLoadEnd() {
      console.log('初始化加载完成')
    },

    /**
    * 初始化加载完成 2023-07-29 10:53:04 Ywr
    * @param {Number} i 当前下标
    */
    funTransitionend(i) {
      this.nowIndex = i
      console.log('当前下标', this.nowIndex)
    },

    /**
    * 切换页函数 2023-07-29 19:06:56 Ywr
    * @param {i} 下标
    * @param {Boolean} st 当前下标
    */
    changePage(i, st = false) {
      // 如果是跳转到某页
      if (st) {
        this.swiperRef.slideTo(i)
      }
      else {
        i < 0 ? (this.swiperRef.prev()) : (this.swiperRef.next())
      }
    }
  }
}
</script>

<style scope lang="scss">

.home-style {
  width: 100vw;
  height: 100vh;

  .first-cont {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    width: 100%;
    height: 100vh;
    .can {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 10vh;
      background: skyblue;
    }
    .child {
      flex: 1;
    }
  }
  img {
    width: 100vw;
    height: 100vh;
  }
}

</style>

移动端:
京东/淘宝/拼多多/得物

滑动左侧图红框部分,整体swiper会切换

滑动右侧图红框部分,整体swiper不会切换,内部的swiper-banner会切换

1690784740829.png

亦或者,内部某些区域(下方列表)需要完成自己的滚动效果

image.png

<template>
<div class="home-style">
  <r-swiper class="swiper" :autoPlay="false" :identifier="false" ref="swiper" @loadEnd="funLoadEnd" @transitionend="funTransitionend " :mobile="true">
    <r-slide>
      <div class="first-cont">
        <img src="../1.png" alt="">
        <!-- 此处添加 noMove属性 cs -->
        <div class="box cs">
           <div class="can cs">
             <div class="cs" v-for="i in 100">{{i}}</div>
           </div>
        </div>
      </div>
    </r-slide>
    <r-slide>
      <img src="../1.png" alt="">
    </r-slide>
    <r-slide>
      <img src="../1.png" alt="">
    </r-slide>
  </r-swiper>
</div>
</template>

<script>
import { rSwiper, rSlide } from 'r-swiper2'

export default {
  data() {
    return {
      nowIndex: 0 // 当前下标
    }
  },

  components: {
    'r-swiper': rSwiper, // 外部组件
    'r-slide': rSlide // 内部组件
  },

  computed: {
    swiperRef() {
      return this.$refs.swiper
    }
  },

  methods: {
    /**
    * 初始化加载完成  2023-07-29 10:53:04 Ywr
    */
    funLoadEnd() {
      console.log('初始化加载完成')
    },
    /**
    * 初始化加载完成 2023-07-29 10:53:04 Ywr
    * @param {Number} i 当前下标
    */
    funTransitionend(i) {
      this.nowIndex = i
      console.log('当前下标', this.nowIndex)
    },

    /**
    * 切换页函数 2023-07-29 10:53:04 Ywr
    * @param {i} 下标
    * @param {Boolean} st 当前下标
    */
    changePage(i, st = false) {
      // 如果是跳转到某页
      if (st) {
        this.swiperRef.slideTo(i)
      }
      else {
        i < 0 ? (this.swiperRef.prev()) : (this.swiperRef.next())
      }
    }
  }
}
</script>

<style scope lang="scss">

.home-style {
  width: 100vw;
  height: 100vh;

 .first-cont {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    width: 100%;
    height: 100vh;

    .box {
      width: 100%;
      height: 20vh;
      overflow-x: scroll;
      .can {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        height: 20vh;

        div {
          background: skyblue;
          border: 1px solid #fff;
          width: 100px;
          padding: 80px;
          margin: 10px;
        }
      }
    }

    img {
      height: 80vh;
    }

    .child {
      flex: 1;
    }
  }
  img {
    width: 100vw;
    height: 100vh;
  }
}

</style>

上面这几种情况都可以使用当前swiper解决。

fast丝滑模式

大家可以试一下swiper官网 以及京东、淘宝,得物的轮播页面,快速滑动时,会有不连贯的感觉
因为在轮播组件内部,会有一个时间段的保护机制,在此时间段内需要等待轮播事件完成的动态效果,此时如果强制滑动会有异常
而本文插件的 fast模式,就可以完美规避这点
只需要设置swiper的 fast即刻开启丝滑模式

<r-swiper fast></r-swiper>

此时就可以实现快速滑动,纵享丝滑

这就是本期的全部内容了,谢谢大家。

感谢

感谢各swiper开源开发者
特别感谢linfeng大佬[https://github.com/helicopters?tab=repositories]

作者

Email: zywr012345@gmail.com

WeChat: ywr_98

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
引用\[1\]:根据提供的引用内容,版本3.1.3是vue-awesome-swiper的一个旧版本。引用\[2\]中提到了如何全局引入vue-awesome-swiper,并且需要引入swiper的CSS文件。引用\[3\]中展示了如何在Vue组件中使用vue-awesome-swiper来实现轮播图。根据您的需求,您想要在切换slide时更换app组件的背景。 为了实现这个需求,您可以在vue-awesome-swiper的slide切换事件中,通过修改app组件的背景样式来实现背景的更换。您可以在Vue组件中监听swiper的slideChange事件,并在事件回调函数中修改app组件的背景样式。 下面是一个示例代码,展示了如何实现这个需求: ```javascript <template> <div id="home-swiper"> <swiper ref="homeSwiper" :options="homeSwiperOptions" @slideChange="handleSlideChange"> <swiper-slide>...</swiper-slide> <swiper-slide>...</swiper-slide> </swiper> </div> </template> <script> import { swiper, swiperSlide } from "vue-awesome-swiper"; import "swiper/dist/css/swiper.css"; export default { components: { swiper, swiperSlide, }, methods: { handleSlideChange() { // 在这里修改app组件的背景样式 // 例如:this.$root.$el.style.background = "red"; }, }, }; </script> ``` 在handleSlideChange方法中,您可以根据需要修改app组件的背景样式。例如,您可以使用`this.$root.$el.style.background`来修改app组件的背景颜色。请根据您的具体需求进行相应的修改。 希望这个示例能够帮助您实现轮播图并更换app组件的背景。如果您有任何其他问题,请随时提问。 #### 引用[.reference_title] - *1* [【npm install vue-awesome-swiper@3.1.3 -S 】下载成功但是vue-awesome-swiper 用不了](https://blog.csdn.net/Sonnenlicht77/article/details/126951340)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [关于swiper的两种用法(swiper@4.0.7 vue-awesome-swiper@3.1.3)](https://blog.csdn.net/weixin_52259399/article/details/129066576)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [vue-awesome-swiper @3.1.3使用,记录一些bug及解决方法](https://blog.csdn.net/gegegegege12/article/details/121387965)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值