1. 程式人生 > >Vue(三十一)輪播組件

Vue(三十一)輪播組件

row jump item translate ted mount flow ack ==

直接上源碼

(1)組件文件 Carousel.vue

<template>
  <div class="carousel-component">
    <div ref="carouselItems" class="carousel-items" :style="carouselStyle" @mouseenter="handleStop" @mouseleave="handlePlay">
      <div class="carousel-items-images">
        <img :src="dataImage[dataImage.length-1].src"  srcset="">
      </div>
      <div class="carousel-items-images" v-for
="(item, index) in dataImage" :key="index"> <img :src="item.src" srcset=""> </div> <div class="carousel-items-images"> <img :src="dataImage[0].src" srcset=""> </div> </div> <div class="carousel-btn"> <div @click="handleJump(index+1)" v-for
="(item, index) in dataImage" :key="index" :class="currentIndex == index+1?‘carousel-btn-items active‘:‘carousel-btn-items‘"></div> </div> </div> </template> <script> export default { name: ‘my-carousel‘, props: { dataImage: { type: Array, default
: function () { return [] } }, initialImgWidth: { type: Number, default: 990 }, initialDistance: { type: Number, default: -990 }, initialSpeed: { type: Number, default: 40 }, initialInterval: { type: Number, default: 3 } }, data () { return { imgWidth: this.initialImgWidth, distance: this.initialDistance, currentIndex: 1, transitionEnd: true, speed: this.initialSpeed } }, computed: { carouselStyle () { return { transform: `translate3d(${this.distance}px, 0, 0)` } }, interval () { return this.initialInterval * 1000 } }, methods: { init () { this.handlePlay() window.onblur = function () { this.handleStop() }.bind(this) window.onfocus = function () { this.handlePlay() }.bind(this) }, move (offset, direction, speed) { // 移動方法 if (!this.transitionEnd) return this.transitionEnd = false direction === -1 ? this.currentIndex += offset / this.imgWidth : this.currentIndex -= offset / this.imgWidth if (this.currentIndex > this.dataImage.length) this.currentIndex = 1 if (this.currentIndex < 1) this.currentIndex = this.dataImage.length 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 < -this.imgWidth*this.currentIndex) this.distance = -this.imgWidth if (des > -this.imgWidth) this.distance = -this.imgWidth*this.currentIndex } }, 20) }, handleJump (index) { // 小圓點點擊跳轉 const direction = index - this.currentIndex >= 0 ? -1 : 1 const offset = Math.abs(index - this.currentIndex) * this.imgWidth const jumpSpeed = Math.abs(index - this.currentIndex) === 0 ? this.speed : Math.abs(index - this.currentIndex) * this.speed this.move(offset, direction, jumpSpeed) }, handlePlay () { // 啟動自動輪播定時器 if (this.timer) { window.clearInterval(this.timer) this.timer = null } this.timer = window.setInterval(() => { this.move(this.imgWidth, -1, this.speed) }, this.interval) }, handleStop () { // 關閉定時器 window.clearInterval(this.timer) this.timer = null } }, mounted () { this.init() } } </script> <style lang="scss" scoped> .carousel-component{ height: 500px; position: relative; overflow: hidden; .carousel-items{ display: flex; position: absolute; width: 100%; height: 100%; .carousel-items-images{ width: 100%; height: 100%; img{ height: 100%; user-select: none; } } } .carousel-btn{ height: 30px; position: absolute; bottom: 20px; left: 0; right: 0; margin: auto; display: flex; flex-direction: row; justify-content: center; align-items: center; .carousel-btn-items{ width: 8px; height: 8px; border-radius: 8px; background-color: #fff; border:1px solid #fd3555; margin:0 3px; cursor: pointer; &.active{ width: 16px; background-color: #fd3555; } } } } </style>

2.父組件中引入

<template>
  <div class="home-page">
    <div class="home-nav">
      <div class="container">
        <div class="left-nav"></div>
        <div class="banner" ref="banner">
          <my-carousel :dataImage="dataImage"></my-carousel>
        </div>
      </div>
    </div>
</template>

<script>
import Carousel from ‘../components/carousel/Carousel‘
export default {
  name: ‘my-home‘,
  data () {
    return {
      dataImage: [{
        src: ‘xxxxxx/banner1.jpg‘
      }, {
        src: ‘xxxxxx/banner2.jpg‘
      }, {
        src: ‘xxxxxx/banner3.jpg‘
      }]
    }
  },
  components: {
    ‘my-carousel‘: Carousel
  }
}
</script>

3.效果

技術分享圖片

Vue(三十一)輪播組件