vue2 封装一个轮播图组件
时间: 2023-11-02 12:07:15 浏览: 86
好的,以下是一个简单的 Vue2 轮播图组件封装:
```vue
<template>
<div class="slider">
<div class="slider__wrapper" :style="{ transform: 'translateX(' + translateX + 'px)' }">
<div v-for="(item, index) in items" :key="index" class="slider__item">
<img :src="item.imgUrl" alt="">
</div>
</div>
<div class="slider__dots">
<span v-for="(item, index) in items" :key="index" :class="{ active: currentIndex === index }" @click="handleDotClick(index)"></span>
</div>
<button class="slider__btn slider__btn--prev" @click="prev">
<i class="iconfont icon-arrow-left"></i>
</button>
<button class="slider__btn slider__btn--next" @click="next">
<i class="iconfont icon-arrow-right"></i>
</button>
</div>
</template>
<script>
export default {
props: {
items: {
type: Array,
required: true
},
interval: {
type: Number,
default: 3000
}
},
data() {
return {
currentIndex: 0,
translateX: 0,
timer: null
}
},
computed: {
wrapperWidth() {
return this.items.length * 100 + '%'
},
itemWidth() {
return 100 / this.items.length + '%'
}
},
mounted() {
this.startAutoPlay()
},
beforeDestroy() {
this.stopAutoPlay()
},
methods: {
startAutoPlay() {
this.timer = setInterval(() => {
this.next()
}, this.interval)
},
stopAutoPlay() {
clearInterval(this.timer)
},
prev() {
this.currentIndex = (this.currentIndex + this.items.length - 1) % this.items.length
this.translateX = -this.currentIndex * this.$el.clientWidth
},
next() {
this.currentIndex = (this.currentIndex + 1) % this.items.length
this.translateX = -this.currentIndex * this.$el.clientWidth
},
handleDotClick(index) {
this.currentIndex = index
this.translateX = -this.currentIndex * this.$el.clientWidth
}
}
}
</script>
<style>
.slider {
position: relative;
overflow: hidden;
}
.slider__wrapper {
display: flex;
transition: transform 0.3s ease-out;
}
.slider__item {
width: 100%;
flex-shrink: 0;
}
.slider__dots {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
}
.slider__dots span {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #ccc;
margin-right: 5px;
cursor: pointer;
transition: background-color 0.3s ease-out;
}
.slider__dots span.active {
background-color: #333;
}
.slider__btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 30px;
height: 30px;
background-color: rgba(0, 0, 0, 0.3);
border: none;
border-radius: 50%;
color: #fff;
cursor: pointer;
transition: background-color 0.3s ease-out;
}
.slider__btn:hover {
background-color: rgba(0, 0, 0, 0.5);
}
.slider__btn i {
font-size: 16px;
line-height: 30px;
}
.slider__btn--prev {
left: 20px;
}
.slider__btn--next {
right: 20px;
}
</style>
```
使用时,可在父组件中引入并传入轮播图数据:
```vue
<template>
<slider :items="items" :interval="3000" />
</template>
<script>
import Slider from '@/components/Slider.vue'
export default {
components: {
Slider
},
data() {
return {
items: [
{
imgUrl: 'https://picsum.photos/800/400?random=1'
},
{
imgUrl: 'https://picsum.photos/800/400?random=2'
},
{
imgUrl: 'https://picsum.photos/800/400?random=3'
}
]
}
}
}
</script>
```
阅读全文