用vue2封装轮播图组件

日常练习

用vue2封装轮播图组件,传入图片信息数组。

实现思想:

  图片组添加translate动画,通过轮播到第几张图片作为参数,让图片组整体移动。

Carousel.vue
复制代码
<template>
  <div class="carousel">
    <div class="carouselList">
      <!-- 图片列表 -->
      <ul class="img">
        <li v-for="(item,index) in imageList" :key="index" :style="move">
          <img :src="item.src" alt="">
        </li>
      </ul>
      <!-- 圆点列表 -->
      <ul class="circle">
        <li v-for="(item,index) in imageList.length" :key="index"
          :style="{'backgroundColor':index==imgStatus?'#ffffffc9':'#ffffff7b'}" @click="circleMove(index)"></li>
      </ul>
      <!-- 左箭头 -->
      <div class="leftArrow" @click="leftMove">&lt;</div>
      <!-- 右箭头 -->
      <div class="rightArrow" @click="rightMove">&gt;</div>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Carousel',
    props: ['imageList'],
    data() {
      return {
        imgStatus: 0, //浏览到第几张图片
        move: null, //图片translate样式
        actionTimer: null, //防抖定时器
        beginTime: 0, //节流
        autoInterval: null //自动轮播定时器
      }
    },
    methods: {
      leftMove() {
        clearInterval(this.autoInterval);
        if (!this.actionTimer) {
          this.imgStatus -= 1;
          if (this.imgStatus <= 4 && this.imgStatus >= 0) this.moveFun();
          if (this.imgStatus == -1) this.imgStatus = 3;
          this.moveFun();
          this.actionTimer = setTimeout(() => {}, 1000);
        } else {
          if (this.actionTimer) clearTimeout(this.actionTimer);
          this.actionTimer = setTimeout(() => {
            this.imgStatus -= 1;
            if (this.imgStatus <= 4 && this.imgStatus >= 0) this.moveFun();
            if (this.imgStatus == -1) this.imgStatus = 3;
            this.moveFun();
          }, 1000);
        };
        this.autoMove();
      },
      rightMove() {
        clearInterval(this.autoInterval);
        let now = new Date().getTime()
        if (now - this.beginTime > 1000) {
          this.imgStatus += 1;
          if (this.imgStatus == 4) this.imgStatus = 0;
          this.moveFun();
          this.beginTime = now;
        };
        this.autoMove();
      },
      circleMove(index) {
        clearInterval(this.autoInterval);
        this.imgStatus = index;
        this.moveFun();
        this.autoMove();
      },
      moveFun() {
        this.move = `transform:translateX(-${this.imgStatus*490}px)`;
      },
      autoMove() {
        this.autoInterval = setInterval(() => {
          if (this.imgStatus >= 0 && this.imgStatus < 3) this.imgStatus += 1;
          else if (this.imgStatus == 3) this.imgStatus = 0;
          else if (this.imageList == -1) this.imgStatus = 0;
          this.moveFun()
        }, 2000);
      }
    },
    mounted() {
      this.autoMove();
    }
  }
</script>

<style scoped>
  .carousel {
    position: relative;
    width: 490px;
    background-color: lightblue;
    display: flex;
    align-items: center;
    justify-content: center;

  }

  .carouselList {
    background-color: lightcoral;
    overflow: hidden;
  }

  .carouselList .img {
    width: 400%;
  }

  .carouselList .img li {
    float: left;
    height: 290px;
    transition: transform 0.3s ease-in-out;
  }

  .carouselList .circle {
    position: absolute;
    bottom: 0;
    left: 195px;
    width: 100px;
    height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .carouselList .circle li {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background-color: #ffffff7b;
    float: left;
    cursor: pointer;
  }

  .leftArrow {
    position: absolute;
    top: 125px;
    width: 50px;
    height: 50px;
    background-color: #cccccc68;
    font-size: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
  }

  .leftArrow:hover {
    background-color: #ccccccc3;
  }

  .rightArrow {
    position: absolute;
    top: 125px;
    right: 0px;
    width: 50px;
    height: 50px;
    background-color: #cccccc68;
    font-size: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
  }

  .rightArrow:hover {
    background-color: #ccccccc3;
  }
</style>
复制代码

App.vue

复制代码
<template>
  <div id="app">
    <Carousel :imageList="imageList"></Carousel>
  </div>
</template>

<script>
import Carousel from './components/Carousel.vue'
export default {
  name: 'App',
  components: {
    Carousel
  },
  data() {
    return {
      imageList: [{
            src: require('./images/1.png')
          },
          {
            src: require('./images/2.png')
          },
          {
            src: require('./images/3.png')
          },
          {
            src: require('./images/4.png')
          }
        ],
    }
  },
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
*{
  box-sizing: border-box;
  margin: 0 auto;
  padding: 0 ;
  user-select: none;
}
li{
  list-style: none;
}
</style>
复制代码

 

 

开发遇到的问题

使用v-for循环图片时,item是图片路径,一开始设置为↓,但是找不到图片资源。

1
'../images/1.png'

后来将途径改为↓,生效。

1
require( '../images/1.png' ) 

原因

vue 项目通过webpack 的 devServer 运行之后,默认的 vue-cli 配置下,图片会被打包成 name.hash 的图片名,在这种情况下,如果我们使用固定的 字符串路径则无法找到该图片,所以需要使用 require 方法来返回 图片的编译路径。

在HTML中可以直接使用普通路径,但在js中需要通过require编译路径。

 

posted @   Karle  阅读(445)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示