版本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>