Vue(三十一)轮播组件

直接上源码

(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.效果

原文地址:https://www.cnblogs.com/yulingjia/p/9797671.html

时间: 2024-10-24 14:34:54

Vue(三十一)轮播组件的相关文章

vue-awesome-swipe 基于vue使用的轮播组件 使用

npm install vue-awesome-swiper --save  //基于vue使用的轮播组件 <template> <swiper :options="swiperOption" ref="mySwiper"> <swiper-slide v-for="(banner,index) in banners" :key="index"> <img v-if="ban

vue使用swiper轮播组件开启loop模式时的问题总结

最近在vue项目中使用了swiper插件来完成轮播功能,没有开启循环模式,一切都很顺利 具体怎么在vue项目中引入swiper插件,这个太简单就不提了,上代码 html <div class="swiper-container"> <div class="swiper-wrapper"> <template v-if='banner.length > 0'> <div class="swiper-slide&

vue中引入awesomeswiper的方法以及编写轮播组件

1.先安装less-loader npm install less less-loader --save 2.再安装css-loader npm install css-loader --save 3.安装上面两个之后.再安装vue-awesome-swiper(必须在前两个安装过之后安装) npm install vue-awesome-swiper --save 4.安装完之后在package.json文件中查看一下,看是否安装上,如果安装成功,里面会显示对应的版本号 "less"

基于Reactive Native轮播组件的应用开发以及移动端模拟器下的调试

总结下这段时间学习reactive native的一些东西,我们来认识一下,被炒得这么火的rn,究竟是个什么东西,以及如何去搭建自己的demo. reactive  native是什么 由facebook开发的一种应用框架,可以用react开发原生应用的框架.简单来说就是可以通过js和react来开发的一种框架. react是什么 一套js的框架,也是facebook开源.特点:jsx语法(类似XML),组件化模式,virtual DOM,单向数据流. 基本模式:每个react应用可视为组件的组

移动端Reactive Native轮播组件

移动端Reactive Native轮播组件 总结下这段时间学习reactive native的一些东西,我们来认识一下,被炒得这么火的rn,究竟是个什么东西,以及如何去搭建自己的demo. reactive  native是什么 由facebook开发的一种应用框架,可以用react开发原生应用的框架.简单来说就是可以通过js和react来开发的一种框架. react是什么 一套js的框架,也是facebook开源.特点:jsx语法(类似XML),组件化模式,virtual DOM,单向数据流

MUI组件四:选择器、滚动条、单选框、区域滚动和轮播组件

目录(?)[+] 1.picker(选择器) mui框架扩展了pipcker组件,可用于弹出选择器,在各平台上都有统一表现.poppicker和dtpicker是对picker的具体实现.*poppicker组件依赖mui.picker.js/.css mui.poppicker.js/.css请务必在mui.js/css后中引用,也可统一引用 压缩版本:mui.picker.min.js (1).popPicker 适用于弹出单级或多级选择器 a.通过new mui.PopPicker()初始

bootstrap轮播组件,大屏幕图片居中效果

在慕课网学习bootstrap轮播组件的时候,了解到轮播的图片都放在了类名为item下的img中 视频中老师对图片自适应采用给图片img设置width=100%完成,然而这样自适应处理图片在不同屏幕中效果不同,大屏效果非常糟糕.比如 这样一张图片, 为了图片自适应设置width=100%,在宽1920px下显示效果是这样的 显然,因为图片设置了100%的宽度,其大部分内容被截去,显示非常糟糕. 后来想了想.有没有办法可以让图片真正的自适应呢并且居中呢,于是想到了css3背景图片属性backgro

【AmazeUI】图片轮播组件

这个组件在IE上一直很火,其实现可以参考<[JavaScript]原生态兼容IE6的图片轮播>(点击打开链接),AmazeUI同样在移动端提供这样的组件. 其效果如下,这个结果要在谷歌.野狐禅等浏览器的手机端调试模式才能看到,在PC端会布局错乱. 用户可以自由滑动,点击下方的圆点,选择自己要浏览的图片,当鼠标悬停在图片上,其组件则不会继续轮播图片. 实现代码如下: <!--使用HTML5开发--> <!doctype html> <html class="

移动端轮播组件swipeslide实现

从前只做过PC端轮播组件,实现方式也是margin负值和setTimeout.前一阵看到一个比较精简的移动端轮播组件的实现https://github.com/ximan/swipeSlide/blob/gh-pages/js/swipeSlide.js,用translate代替margin负值,并且添加了对touch事件的处理.在这里总结一下这个组件的实现. 所有的li绝对定位于容器左上角,宽度100%,高度100%. 1.组件init步骤: 1)如果设定了连续轮播,则复制first slid

mobile轮播组件——支持事件回调和队列(原生js实现)

mobile轮播组件,支持图片不定高,支持事件回调,队列,兼容主流webkit浏览器 demo地址:http://7li.github.io/components/swipe/ demo二维码: 测试地址:http://7li.github.io/components/swipe/test/ 仓库地址:https://github.com/7LI/swipe 本文出自:http://blog.csdn.net/nancle/article/details/44937531 仓促之际必有疏漏,请各