vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue实现轮播图

vue实现轮播图的多种方式

作者:竹竹竹竹竹子

这篇文章给大家介绍了vue实现轮播图的多种方式,文中给出了四种实现方式,并通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,感兴趣的朋友可以参考下

版本01 比较生硬

<template>
  <div>
    <div
      class="carousel_middle_img"
      @mouseover="changeInterval(true)"
      @mouseleave="changeInterval(false)"
      v-for="(item, index) in imgArr"
      :key="'a' + index"
      :style="{ background: 'url(' + item.url + ')' }"
      v-show="index === currentIndex"
    >
      <!-- 左侧按钮 -->
      <div
        @click="clickIcon('up')"
        class="carousel_middle_img_left_icon"
        v-show="isShow"
      ></div>
      <!-- 右侧按钮 -->
      <div
        @click="clickIcon('down')"
        class="carousel_middle_img_right_icon"
        v-show="isShow"
      ></div>
    </div>
    <!-- 控制圆点 -->
    <ul
      class="carousel_banner_circle"
      @mouseover="changeInterval(true)"
      @mouseleave="changeInterval(false)"
    >
      <li
        @click="changeImg(item.id)"
        v-for="(item, index) in imgArr"
        :key="index"
        :class="index === currentIndex ? 'active' : ''"
      ></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "Carousel",
  data() {
    return {
      isShow: false,
      isMouseEntered: false,
      currentIndex: 0, //当前所在图片下标
      timer: null //定时轮询
    };
  },
  props: {
    theme:"",
    imgArr: {
      type: Array,
      required: true
    }
  },

  methods: {
    startInterval() {
      clearInterval(this.timer);
      this.timer = setInterval(() => {
        this.currentIndex = (this.currentIndex + 1) % this.imgArr.length;
      }, 3000);
    },
    clickIcon(val) {
      if (val === "down") {
        this.currentIndex++;
        if (this.currentIndex === this.imgArr.length) {
          this.currentIndex = 0;
        }
      } else {
        if (this.currentIndex === 0) {
          this.currentIndex = this.imgArr.length;
        }
        this.currentIndex--;
      }
    },
    //点击控制圆点
    changeImg(index) {
      this.currentIndex = index;
    },
    //鼠标移入移出控制
    changeInterval(val) {
      if (val) {
        clearInterval(this.timer);
        this.isShow = true;
      } else {
        this.startInterval();
        this.isShow = false;
      }
    },
  },
  //进入页面后启动定时轮询
  mounted() {
    this.startInterval();
  },
  watch: {
    currentIndex: {
      handler(val) {
        this.$emit("imgIdOnShow", val);
      },
      immediate: true
    }
  }
};
</script>
<style scoped>
* {
  padding: 0;
  margin-left: 0;
}
li {
  list-style-type: none;
}
.carousel_middle_img {
  position: relative;
  width: 280px;
  height: 160px;
  background-size: cover !important;
  z-index: 100;
}
.carousel_middle_img_left_icon {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 20px;
  left: 0px;
  background-image: url("./icon_left.png");
  background-size: 16px 20px;
}
.carousel_middle_img_right_icon {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 20px;
  right: 0px;
  background-image: url("./icon_right.png");
  background-size: 16px 20px;
}
.carousel_banner_circle {
  position: absolute;
  display: flex;
  height: 12px;
  top: 156px;
  left: 292px;
  border-radius: 7px;
  background-color: rgba(0, 0, 0, 0.15);
}
.carousel_banner_circle li {
  width: 6px;
  height: 6px;
  margin: 3px 4px;
  border-radius: 5px;
  background-color: #ffffff;
  opacity: 0.5;
}
.active {
  background-color: #ffffff !important;
  opacity: 1 !important;
}
</style>

01silde

<template>
    <div class="carousel_container">
        <div
                class="carousel_middle_img"
                @mouseover="changeInterval(true)"
                @mouseleave="changeInterval(false)"
                v-for="(item, index) in imgArr"
                :key="'a' + index"
                :style="{ background: 'url(' + item.url + ')' }"
                v-show="index === currentIndex"
        >
            <!-- 左侧按钮 -->
            <div
                    @click="clickIcon('up')"
                    class="carousel_middle_img_left_icon"
                    v-show="isShow"
            ></div>
            <!-- 右侧按钮 -->
            <div
                    @click="clickIcon('down')"
                    class="carousel_middle_img_right_icon"
                    v-show="isShow"
            ></div>
        </div>
        <div
                class="carousel_right_img"
                @mouseover="moveImage(item.id)"
                v-for="(item, index) in imgArr"
                :key="'b' + index"
                :style="{ background: 'url(' + item.url + ')' }"
                v-show="index === (currentIndex + 1) % imgArr.length"
        ></div>
        <div
                class="carousel_left_img"
                @mouseover="moveImage(item.id)"
                v-for="(item, index) in imgArr"
                :key="'c' + index"
                :style="{ background: 'url(' + item.url + ')' }"
                v-show="index === (currentIndex + imgArr.length - 1) % imgArr.length"
        ></div>
        <!-- 控制圆点 -->
        <ul
                class="carousel_banner_circle"
                @mouseover="changeInterval(true)"
                @mouseleave="changeInterval(false)"
        >
            <li
                    @click="changeImg(item.id)"
                    v-for="(item, index) in imgArr"
                    :key="index"
                    :class="index === currentIndex ? 'active' : ''"
            ></li>
        </ul>
    </div>
</template>

<script>
    export default {
        name: "Carousel",
        data() {
            return {
                isShow: false,
                isMouseEntered: false,
                currentIndex: 0, //当前所在图片下标
                timer: null //定时轮询
            };
        },
        props: {
            theme:"",
            imgArr: {
                type: Array,
                required: true
            }
        },

        methods: {
            startInterval() {
                clearInterval(this.timer);
                this.timer = setInterval(() => {
                    this.currentIndex = (this.currentIndex + 1) % this.imgArr.length;
                }, 3000);
            },
            clickIcon(val) {
                if (val === "down") {
                    this.currentIndex++;
                    if (this.currentIndex === this.imgArr.length) {
                        this.currentIndex = 0;
                    }
                } else {
                    if (this.currentIndex === 0) {
                        this.currentIndex = this.imgArr.length;
                    }
                    this.currentIndex--;
                }
            },
            //点击控制圆点
            changeImg(index) {
                this.currentIndex = index;
            },
            //鼠标移入移出控制
            changeInterval(val) {
                if (val) {
                    clearInterval(this.timer);
                    this.isShow = true;
                } else {
                    this.startInterval();
                    this.isShow = false;
                }
            },
            //移入左右图片放大
            moveImage(index) {
                if (!this.isMouseEntered) {
                    clearInterval(this.timer);
                    this.currentIndex = index;
                    this.isMouseEntered = true;
                } else {
                    this.startInterval();
                    this.isMouseEntered = false;
                }
            }
        },
        //进入页面后启动定时轮询
        mounted() {
            this.startInterval();
        },
        watch: {
            currentIndex: {
                handler(val) {
                    this.$emit("imgIdOnShow", val);
                },
                immediate: true
            }
        }
    };
</script>
<style scoped>
    * {
        padding: 0;
        margin-left: 0;
    }
    li {
        list-style-type: none;
    }
    .carousel_container {
        position: relative;
        text-align: justify;
        width: 640px;
        height: 184px;
    }
    .carousel_middle_img {
        position: absolute;
        left: 180px;
        width: 280px;
        height: 160px;
        background-size: cover !important;
        z-index: 100;
    }
    .carousel_left_img {
        top:10px;
        opacity: 0.4;
        left: 0;
        position: absolute;
        width: 240px;
        height: 136px;
        background-size: cover !important;
    }
    .carousel_right_img {
        top:10px;
        background-size: cover !important;
        opacity: 0.4;
        right: 0;
        position: absolute;
        width: 240px;
        height: 136px;
    }
    .carousel_middle_img_left_icon {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 16px;
        height: 20px;
        left: 0px;
        background-image: url("./icon_left.png");
        background-size: 16px 20px;
    }
    .carousel_middle_img_right_icon {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 16px;
        height: 20px;
        right: 0px;
        background-image: url("./icon_right.png");
        background-size: 16px 20px;
    }
    .carousel_banner_circle {
        position: absolute;
        display: flex;
        height: 12px;
        top: 156px;
        left: 292px;
        border-radius: 7px;
        background-color: rgba(0, 0, 0, 0.15);
    }
    .carousel_banner_circle li {
        width: 6px;
        height: 6px;
        margin: 3px 4px;
        border-radius: 5px;
        background-color: #ffffff;
        opacity: 0.5;
    }
    .active {
        background-color: #ffffff !important;
        opacity: 1 !important;
    }
</style>

水平轮播

<template>
<div class="carousel">
    <div class="carousel_container"
         @mouseover="changeInterval(true)"
         @mouseleave="changeInterval(false)">
      <img
        v-for="(item, index) in imgArr"
        :key="index"
        :src="item.url"
        :style="{ left: index * 100 + '%', transform: Style }"
      />
        <div   class="carousel_middle_img_left_icon" v-show="isShow" @click="prev()"></div>
        <div   class="carousel_middle_img_right_icon" v-show="isShow" @click="next()" ></div>
        <div  v-show="theme==='Normal_one'"
              class="carousel_banner">
            <div class="carousel_banner_circle"
                 v-show="isShow"
                 @click="changeImg(index)"
                 v-for="(item, index) in imgArr"
                 :key="'b' + index"
                 :class="index === currentIndex ? 'active' : ''"
            ></div>
        </div>
    </div>
    <div  v-show="theme==='Normal_two'"
          class="carousel_banner">
        <div class="carousel_banner_circle"
             @click="changeImg(index)"
             v-for="(item, index) in imgArr"
             :key="'c' + index"
             :class="index === currentIndex ? 'active' : ''"
        ></div>
    </div>
</div>
</template>
<script>
export default {
  data() {
    return {
      Style: "",
      currentIndex: 0,
      timer: null,
      isShow: false,
      config: []
    };
  },
  props: {
      theme:"",
      imgArr: {
      type: Array,
      required: true
    }
  },
  mounted() {
    // 自动播放动画
    this.startInterval();
  },
  methods: {
      // 定时器
      startInterval() {
          this.timer = setInterval(() => {
              this.currentIndex = (this.currentIndex + 1) % this.imgArr.length;
              this.setStyle();
          }, 3000);
      },
      changeInterval(val) {
          if (val) {
              clearInterval(this.timer);
              this.isShow = true;
          } else {
              this.startInterval();
              this.isShow = false;
          }
      },
    next() {
      this.currentIndex = (this.currentIndex + 1) % this.imgArr.length;
      this.setStyle();
    },
    prev() {
        this.config.push(this.config.shift());
      this.currentIndex = (this.currentIndex - 1 + this.imgArr.length) % this.imgArr.length;
      this.setStyle();
    },
    // 图片动画
    setStyle() {
      this.Style = `translatex(-${this.currentIndex * 100}%)`;
    },
      //点击控制圆点
      changeImg(index) {
          if(index > this.currentIndex){
              for(let i = 0;i<= index - this.currentIndex;i++){
                  this.next();
              }
          }else if(index < this.currentIndex){
              for(let i = 0;i<= this.currentIndex - index;i++){
                  this.prev();
              }
          }
          this.currentIndex = index;
      },
  }
};
</script>
<style scoped>
    .carousel{
        position: relative;
        width: 100%;
        height: 340px;
    }
  .carousel_container {
  position: relative;
  width: 100%;
  height: 300px;
  overflow: hidden;
}
.carousel_container img {
  display: inline-block;
  position: absolute;
  width: inherit;
  margin: 0;
  padding: 0;
  top: 0;
  left: 0;
  height: 100%;
  transition: 0.5s transform ease-in-out;
}
.carousel_middle_img_left_icon {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 20px;
    left: 0px;
    background-image: url("./icon_left.png");
    background-size: 16px 20px;
    z-index: 999;
}
.carousel_middle_img_right_icon {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 20px;
    right: 0px;
    background-image: url("./icon_right.png");
    background-size: 16px 20px;
    z-index: 999;
}
  .carousel_banner {
      position: absolute;
      display: flex;
      height: 3.6%;
      left: 50%;
      transform: translate(-50%);
      bottom: 4%;
      margin-bottom: 0;
      padding-left: 0;
      border-radius: 7px;
      background-color: rgba(0, 0, 0, 0.15);
  }
  .carousel_banner_circle{
      width: 6px;
      height: 6px;
      margin: 3px 6px;
      border-radius: 5px;
      background-color: #ffffff;
      opacity: 0.5;
  }
  .active {
      background-color: #ffffff !important;
      opacity: 1 !important;
  }

</style>

垂直实现卡片轮播

<template>
  <div>
    <div>
      <div
        class="carousel_container"
        @mouseover="changeInterval(true)"
        @mouseleave="changeInterval(false)"
      >
        <div
          v-for="(item, index) in imgArr"
          :style="config[index]"
          :key="index"
        >
          <img :src="item.url" style="width: 100%; height: 100%;" />
        </div>
        <div class="carousel_mid_img"></div>
        <div class="carousel_left_img" @click="prev()"></div>
        <div class="carousel_right_img" @click="next()"></div>
        <div class="carousel_banner">
          <div class="carousel_banner_circle"
            @click="changeImg(index)"
            v-for="(item, index) in imgArr"
            :key="'b' + index"
            :class="index === currentIndex ? 'active' : ''"
          ></div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "Carousel",
  data() {
    return {
      timer: null,
      currentIndex: 0,
      startX: "",
      endX: "",
      config: [
        {
          id: "left",
          position: "absolute",
          width: "48%",
          height: "74%",
          top: "8%",
          left: "0",
          opacity: 0.4,
          zIndex: 1,
          transition: ".3s"
        },
        {
          id: "center",
          position: "absolute",
          width: "59%",
          height: "91%",
          top: "0px",
          left: "20%",
          opacity: 1,
          zIndex: 2,
          transition: ".3s"
        },
        {
          id: "right",
          position: "absolute",
          width: "48%",
          height: "74%",
          top: "8%",
          right: "0",
          opacity: 0.4,
          zIndex: 1,
          transition: ".3s"
        }
      ]
    };
  },
  props: {
    imgArr: {
      type: Array,
      required: true
    }
  },
  methods: {
    //定时器
    startInterval() {
      clearInterval(this.timer);
      this.timer = setInterval(() => {
         this.next();
      }, 3000);
    },
    //鼠标移入移出控制
    changeInterval(val) {
      if (val) {
        clearInterval(this.timer);
      } else {
        this.startInterval();
      }
    },
    prev() {
      this.config.push(this.config.shift());
      this.currentIndex = (this.currentIndex + this.imgArr.length - 1) % this.imgArr.length;
      this.centerIndex("prev");
    },
    next() {
      this.config.unshift(this.config.pop());
      this.currentIndex = (this.currentIndex + 1) % this.imgArr.length;
      this.centerIndex("next");
    },

    //点击控制圆点
    changeImg(index) {
      if(index > this.currentIndex){
         for(let i = 0;i<= index - this.currentIndex;i++){
             this.next();
           }
      }else if(index < this.currentIndex){
        for(let i = 0;i<= this.currentIndex - index;i++){
            this.prev();
        }
      }
      this.currentIndex = index;
    },
    // 当前imgArr在位置上的index(并非img数组的index)
    centerIndex(val) {
      if (val == "prev") {
        for (let val of this.imgArr) {
          if (val.index == this.imgArr.length - 1) {
            val.index = 0;
          } else {
            val.index = val.index + 1;
          }
        }
      } else {
        for (let val of this.imgArr) {
          if (val.index == 0) {
            val.index = this.imgArr.length - 1;
          } else {
            val.index = val.index - 1;
          }
        }
      }
    },
    //增加图片数目
    addCardStyle() {
      if (this.imgArr.length > 3) {
        for (let i = 0; i < this.imgArr.length - 3; i++) {
          this.config.push({
            id: "center",
            position: "absolute",
            width: "44%",
            height: "87%",
            top: "0px",
            left: "28%",
            opacity: 0,
            transition: ".3s"
          });
        }
      }
    }
  },
  mounted() {
    this.startInterval();
  },
  watch: {
    currentIndex: {
      handler(val) {
        this.$emit("imgOnShow", this.imgArr[val]);
      },
      immediate: true
    }
  },
  created() {
    this.addCardStyle(); // 加入样式位置的index
  }
};
</script>

<style scoped>
.carousel_container {
  width: 100%;
  height: 328px;
  position: relative;
  overflow: hidden;
}
.carousel_mid_img {
  top: 0;
  left: 20%;
  position: absolute;
  width: 59%;
  height: 91%;
  z-index: 100;
}
.carousel_left_img {
  position: absolute;
  width: 20%;
  height: 74%;
  top: 8%;
  left: 0;
  z-index: 99 !important;
}
.carousel_right_img {
  position: absolute;
  width: 21%;
  height: 74%;
  top: 8%;
  right: 0;
  z-index: 99 !important;
}
.carousel_banner {
  position: absolute;
  display: flex;

  height: 3.6%;
  left: 50%;
  transform: translate(-50%);
  bottom: 0;
  margin-bottom: 0;
  padding-left: 0;
  border-radius: 7px;
  background-color: rgba(0, 0, 0, 0.15);
}
.carousel_banner_circle{
  width: 6px;
  height: 6px;
  margin: 3px 6px;
  border-radius: 5px;
  background-color: #ffffff;
  opacity: 0.5;
}
.active {
  background-color: #ffffff !important;
  opacity: 1 !important;
}
</style>

test.vue

<template>
  <div class="div_container">
<!--    v-bind (:)将元素item-left的属性与组件的itemLeft属性保持一致-->
<!--      <transfer-box :title="title" :item-left="itemLeft" :item-right="itemRight" :theme="theme" @selectedItem="selectedItem"></transfer-box>-->
<!--      <transfer-box :title="title" :item-left="itemLeft" :item-right="itemRight" @selectedItem="selectedItem" />-->
<!--      <Carousel :img-arr="imgArr" @imgOnShow="imgOnShow"></Carousel>-->
      <carousel-horizontal :img-arr="imgArr" :theme="theme" @imgOnShow="imgOnShow"></carousel-horizontal>
  </div>
</template>

<script>
import CarouselHorizontal from "../components/Carousel/CarouselHorizontal"
export default {
    components: {CarouselHorizontal},
    data() {
    return {
        theme:'Normal_two',
        imgArr: [
            { id: 0,
                url: require("../components/Carousel/fig1.jpg"),
            },
            {
                id: 1,
                url: require("../components/Carousel/fig2.jpg"),
            },
            {
                id: 2,
                url: require("../components/Carousel/fig4.jpg"),
            },
            {
                id: 3,
                url: require("../components/Carousel/fig5.png"),
            }
        ]
    };
  },
    methods: {
        imgOnShow(item) {
            console.log(item)
        }
    }
};
</stricpt>

到此这篇关于vue实现轮播图的多种方式的文章就介绍到这了,更多相关vue实现轮播图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文