使用Vue制作图片轮播组件思路详解(7)

window.onblur = function() { this.stop() }.bind(this)
window.onfocus = function() { this.play() }.bind(this)

2. window.setInterval() 小坑

当定时器 window.setInterval() 在多个异步回调中使用时,就有可能在某种机率下开启多个执行队列, 所以为了保险起见,不仅应该在该清除时清除定时器,还要在每次使用之前也清除一遍 。

八、用props简单写两个对外接口

props: {
  initialSpeed: {
   type: Number,
   default: 30
  },
  initialInterval: {
   type: Number,
   default: 4
  }
},
data() {
  ......
  speed: this.initialSpeed  
},
computed:{
  interval() {
    return this.initialInterval * 1000
  }
}

然后再在相应的地方修改下就可以了。

完整的代码如下:

<template>
 <div id="slider">
  <div class="window" @mouseover="stop" @mouseleave="play">
   <ul class="container" :style="containerStyle">
    <li>
     <img :src="sliders[sliders.length - 1].img" alt="">
    </li>
    <li v-for="(item, index) in sliders" :key="index">
     <img :src="item.img" alt="">
    </li>
    <li>
     <img :src="sliders[0].img" alt="">
    </li>
   </ul>
   <ul class="direction">
    <li class="left" @click="move(600, 1, speed)">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>     
    </li>
    <li class="right" @click="move(600, -1, speed)">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>     
    </li>
   </ul>
   <ul class="dots">
    <li v-for="(dot, i) in sliders" :key="i" 
    :class="{dotted: i === (currentIndex-1)}"
    @click = jump(i+1)
    >
    </li>
   </ul>
  </div>
 </div>
</template>
<script>
export default {
 name: 'slider',
 props: {
  initialSpeed: {
   type: Number,
   default: 30
  },
  initialInterval: {
   type: Number,
   default: 4
  }
 },
 data () {
  return {
   sliders:[
    {
     img:'../../static/images/1.jpg'
    },
    {
     img:'../../static/images/2.jpg'
    },
    {
     img:'../../static/images/3.jpg'
    },
    {
     img:'../../static/images/4.jpg'
    },
    {
     img:'../../static/images/5.jpg'
    }
   ],
   currentIndex:1,
   distance:-600,
   transitionEnd: true,
   speed: this.initialSpeed
  }
 },
 computed:{
  containerStyle() {
   return {
    transform:`translate3d(${this.distance}px, 0, 0)`
   }
  },
  interval() {
   return this.initialInterval * 1000
  }
 },
 mounted() {
  this.init()
 },
 methods:{
  init() {
   this.play()
   window.onblur = function() { this.stop() }.bind(this)
   window.onfocus = function() { this.play() }.bind(this)
  },
  move(offset, direction, speed) {
   if (!this.transitionEnd) return
   this.transitionEnd = false
   direction === -1 ? this.currentIndex += offset/600 : this.currentIndex -= offset/600
   if (this.currentIndex > 5) this.currentIndex = 1
   if (this.currentIndex < 1) this.currentIndex = 5
   const destination = this.distance + offset * direction
   this.animate(destination, direction, speed)
  },
  animate(des, direc, speed) {
   if (this.temp) { 
    window.clearInterval(this.temp)
    this.temp = null 
   }
   this.temp = window.setInterval(() => {
    if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
     this.distance += speed * direc
    } else {
     this.transitionEnd = true
     window.clearInterval(this.temp)
     this.distance = des
     if (des < -3000) this.distance = -600
     if (des > -600) this.distance = -3000
    }
   }, 20)
  },
  jump(index) {
   const direction = index - this.currentIndex >= 0 ? -1 : 1
   const offset = Math.abs(index - this.currentIndex) * 600
   const jumpSpeed = Math.abs(index - this.currentIndex) === 0 ? this.speed : Math.abs(index - this.currentIndex) * this.speed 
   this.move(offset, direction, jumpSpeed)
  },
  play() {
   if (this.timer) {
    window.clearInterval(this.timer)
    this.timer = null
   }
   this.timer = window.setInterval(() => {
    this.move(600, -1, this.speed)
   }, this.interval)
  },
  stop() {
   window.clearInterval(this.timer)
   this.timer = null
  }
 }
}
</script>
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/86.html