vue项目中用better-scroll制作轮播图

主要html架构

 

解释:

  1. slider-wrapper是外层容器,它的宽度是更外层容器的宽度,比如在父组件中

  1. slider-ul是图片组ul的宽度,宽度是slider-li的数量 * slider-li的width
  2. slider-li是一个图片项
  3. imgDatas是图片的数据数组

主要CSS代码

/* slider组件的主要CSS代码 */

.slider-wrapper {
  position: relative;
  width: 100%;   /*撑满父容器*/
  height: 100%;  /*撑满父容器*/
  min-height: 1px;
  overflow: hidden;
}

.slider-ul { 
  /* mounted的时候设定ul的宽度,设定方法是100% x 多少个图片item,如5个图片项则是500% */
  /* 如果是假数据进行样式设定调试,可以先设定width为多少个100%  */
  position: relative;
  white-space: nowrap;
  overflow: hidden;   /*清除浮动*/
  height: 100%;
}

.slider-li {
  /* 同样是 mounted时设定一个item的宽度,宽度要和slider-wrapper的宽度一样,则 500% * 0.2 = 100% */
  /* 同样是假数据的样式调试的时候,可以先设定width,如slider-wrapper为100%,slider-ul为500%,即有五张图片,此时设定slider-li的width为20%,500 * 0.2 = 100,则和slider-wrppaer宽度一致 */
  height: 100%;
  float: left;   /*要设置浮动*/
  box-sizing: border-box;
  overflow: hidden;
}

.slider-li a {
  overflow: hidden;
  width: 100%;
  height: 100%;
  display: block;
}

.slider-li img {
  width: 100%;
  height: 100%;
  display: block;
}

组件主要部分

  1. 安装:npm install better-scroll --save
  2. 在slider组件中引入:import BScroll from ‘better-scroll’
// props,父组件传入子组件的参数
props: {
  loop: {      //是否循环播放
    type: Boolean,
    default: true
  },
  autoPlay: {  //是否自动播放
    type: Boolean,
    default: true
  },
  interVal: {  //轮播一张图片的时间
    type: Number,
    default: 3000
  },
  imgDatas: {  //传入的imgDatas数据
    type: Array,
    default: []
  }
}
//主要内置数据
data() {
  return {
    currentPageIndex: 0  //记录当前是哪一张轮播图图片,下标从0开始,即第一张
  }
}
//methods
methods:{
    //第一步,根据传入的imgDatas初始化slider-ul,slider-li的宽度,为百分比
    //注意,better-scroll在初始化时,当你设定了loop的时候,会在前后自动增加2张图片,例如5张图片会变成7张
    //由于这是第一步,暂时没有初始化better-scroll,所以获取children的时候,只是5张图片,props的loop为true时,要加多两个,然后设定ul,li的宽度
    _setUlWidth() {
      this.children = this.$refs.sliderUl.children
      let childrenLength = this.loop ? this.children.length + 2 : this.children.length
      this.$refs.sliderUl.style.width = childrenLength * 100 + '%'
      for (var i = 0; i < this.children.length; i++) {
        this.children[i].style.width = 100 / childrenLength + '%'
      }
    },
    
    //第二步,初始化better-scroll
    _initSlider() {
      let that = this
      this.slider = new BScroll(this.$refs.sliderWrapper, {
        scrollX: true,
        scrollY: false,
        momentum: false,
        snap: {
          loop: this.loop,
          threshold: 0.3,
          speed: 400
        },
        probeType: 2
      })
      //监听scroll结束的时候,赋值更新currentPageIndex
      this.slider.on('scrollEnd', () => {
        clearInterval(that.timer)
        that.currentPageIndex = that.slider.getCurrentPage().pageX
        let childrenLength = this.loop ? this.children.length - 2 : this.children.length
        that._setAutoplay()
      })
      let childrenLength = this.loop ? this.children.length - 2 : this.children.length
      //无缝
      this.checkScroll(childrenLength,this.$refs.sliderWrapper.offsetWidth)
    },
    
    //第三步,设置自动播放
    //这一步不需要重新设定currentPageIndex ,因为转到下一页时触发了scrollEnd事件,已经自动赋值更新
    _setAutoplay() {
      let goToIndex = this.currentPageIndex + 1
      let childrenLength = this.loop ? this.children.length - 2 : this.children.length
      //设置右滑到最后一张的无缝切换,返回到第一张
      if (goToIndex >= childrenLength) {
        goToIndex = 0
      }
      this.timer = setInterval(() => {
        this.slider.goToPage(goToIndex, 0, 400)
      }, this.interVal)
    },
    
    //监听滑事件
    checkScroll(childrenLength,itemWidth) {
      let that = this
      this.slider.on('scroll', () => {
        clearInterval(that.timer)
        let leftScroll = parseInt(that.$refs.sliderUl.style['transform'].substring(10, 15))
        let left = -1 * itemWidth
        let right = left * childrenLength
        if (leftScroll >left) {
          that.slider.goToPage(childrenLength, 0, 400)
        }else if(leftScroll < right) {
          that.slider.goToPage(1, 0, 400)
        }
      })
    }
},
mounted() {
    setTimeout(() => {
      this._setUlWidth()
      this._initSlider()
      this._setAutoplay()
    }, 20)
    window.addEventListener('resize', () => {
      if (!this.slider) {
        return
      }
      this._setUlWidth()
    })
}

这样已经可以轮播了哦,更详细的样式和功能代码看下面的源代码


源代码
使用说明:

imgDatas: [
 { imgSrc: require("./images/1.jpg"), linkUrl: '#' },
 { imgSrc: require("./images/2.jpg"), linkUrl: '#' },
 { imgSrc: require("./images/3.jpg"), linkUrl: '#' },
 { imgSrc: require("./images/4.jpg"), linkUrl: '#' },
]






你可能感兴趣的:(vue插件)