to achieve better-scroll FIG carousel assembly

Started

Based on the time to achieve a better-scroll movable end vertical scrolling presentation. This time, continue to use it to achieve a horizontal scroll - Carousel view of the assembly. Presentation as follows:

First, let's sort out the demand:

  • FIG rotation can be performed based on the image data shows an asynchronous request to.
  • Whether it is possible to control the automatic playing, whether loop, automatically playing interval.
  • You can prompt the current playback page.

Here Insert Picture Description

Mock Data

Because it is a demo, a few pictures from the Internet to find written in json format, data for analog interface data. Here used mock.js. Axios. Installation is as follows:

npm install mockjs
npm install --save axios vue-axios

axios much repeated use, briefly mock data. In the mock folder to place the new folder json json data files. New index.js export interface. You can use the request interface axios.

[
	"https://img3.mukewang.com/szimg/5df8852609e0762d12000676-360-202.png",
    "https://img1.mukewang.com/szimg/5d9c62fb0907ccf012000676-360-202.png",
    "https://img3.mukewang.com/5aeecb1d0001e5ea06000338-360-202.jpg"
]
const Mock = require('mockjs')

Mock.mock('/slider', 'get', require('./json/slider.json'))

Basic components: slider.vue

The carousel assembly of FIG abstract, receiving isLoop, isAutoPlay, interval control rotation property FIG. From the calling sequence mounted way to know the idea is

  • setSliderWidth () Gets the first layer and then set the display picture package height.
  • initDots () array is placed dot images arranged according to the number of sub-elements wrapped layer.
  • initSlider () initializes better-scroll.
  • autoPlay () Set up automatic playback.
<template>
  <div class="slider-apply" ref="slider">  <!-- 显示层 -->
    <div class="slider-group" ref="group"> <!-- 所有图片包裹层 -->
      <slot></slot>                        <!-- 插槽显示图片内容 -->
    </div>
    <div class="dots">                     <!-- 提示圆点 -->
      <div class="dot" v-for="(item, index) in dots" :key="index" :class="currentIndex===index?'active':''"></div>
    </div>
  </div>
</template>

<script type='text/ecmascript-6'>
import BScroll from 'better-scroll'
export default {
  data () {
    return {
      dots: [],
      currentIndex: 0 /* 当前页下标 */
    }
  },
  props: {
    isLoop: { /* 循环播放 */
      type: Boolean,
      default: true
    },
    isAutoPlay: { /* 自动播放 */
      type: Boolean,
      default: true
    },
    interval: { /* 播放间隔 */
      type: Number,
      default: 2000
    }
  },
  mounted () { /* mounted阶段dom渲染完,20ms确保刷新 */
    setTimeout(() => {
      this.setSliderWidth()
      this.initDots()
      this.initSlider()
      if (this.isAutoPlay) {
        this.autoPlay()
      }
    }, 20)
  },
  methods: {
    setSliderWidth () { /* 获取显示层宽度,计算内容层宽度 */
      const clientWidth = this.$refs.slider.clientWidth
      let sliderWidth = 0
      this.children = this.$refs.group.children
      for (let i = 0; i < this.children.length; i++) {
        this.children[i].style.width = clientWidth + 'px'
        sliderWidth += clientWidth
      }
      if (this.isLoop) { /* 循环播放需要增加前后两个宽度 */
        sliderWidth += clientWidth * 2
      }
      this.$refs.group.style.width = sliderWidth + 'px' /* 设置内容层宽度 */
    },
    initDots () {
      this.dots = new Array(this.children.length)
    },
    initSlider () {
      this.slider = new BScroll(this.$refs.slider, {
        scrollX: true, /* 横向滚动 */
        scrollY: false,
        snap: { /* 循环滚动设置 */
          loop: this.isLoop,
          threshold: 0.3,
          speed: 400
        }
      })
      this.slider.on('scrollEnd', () => {
        const pageIndex = this.slider.getCurrentPage().pageX /* 获取当前轮播页,用于圆点提示 */
        this.currentIndex = pageIndex
        if (this.isAutoPlay) {
          clearTimeout(this.timer) /* 重新设置自动播放,否则无法自动播放 */
          this.autoPlay()
        }
      })
    },
    autoPlay () {
      this.timer = setTimeout(() => {
        this.slider.next(400)
      }, this.interval)
    }
  },
  destroyed () { /* 确保清除定时器 */
    clearTimeout(this.timer)
  }
}
</script>

<style lang="stylus" scoped>
.slider-apply
  position relative             // 让dots找准位置
  height 200px
  width 100%                    // slider-apply会依据父元素宽度显示宽度
  overflow hidden               //  超出元素隐藏
  border-radius 5px
  .dots
    position absolute
    bottom 10px
    left 50%
    transform translate(-50%, 0) // 居中
    display flex
    .dot
      margin 0 10px
      height 7px
      width 7px
      background #fff
      border-radius 50%
    .active                     // 当前dot样式
      width 15px
      border-radius 50% 5px
</style>

Application components: slider-apply.vue

You can alider-apply.vue in to use the application in their own projects.

<template>
  <div class="slider-wrapper">
    <Slider v-if="showSlider"> <!-- showSlider使得数据请求完成后再显示,否则better-scroll可能会计算错误 -->
      <div v-for="item in imageList" :key="item" class="slider-item">
        <img :src="item" class="img">
      </div>
    </Slider>
  </div>
</template>

<script type='text/ecmascript-6'>
import Slider from 'base/slider'
export default {
  data () {
    return {
      imageList: [], // 图片列表
      showSlider: false // 显示slider标志位
    }
  },
  created () {
    this.getImages() // 获取数据
  },
  methods: {
    getImages () {
      this.axios.get('/slider').then((res) => {
        this.imageList = res.data
        this.showSlider = true
      }).catch((err) => {
        console.log(err)
      })
    }
  },
  components: {
    Slider
  }
}
</script>

<style lang="stylus" scoped>

.slider-wrapper
  margin 0 auto
  height 200px  // 固定轮播图显示高度
  width 500px   // 固定轮播图显示宽度,可设置百分比
  background #000
  border-radius 5px
  .slider-item
    float left // 元素向左浮动
    width 100%
    overflow hidden
    text-align center
  .img
    height 200px
    width 100%

</style>

If the above steps do not understand, you can find the source code https://github.com/Gesj-yean/vue-demo-collection in my github.

Published 27 original articles · won praise 4 · Views 2817

Guess you like

Origin blog.csdn.net/qq_39083496/article/details/104259280