采用vue2+element-ui,将elementui中carousel中item.vue组件内容复制创建新的swiper组件,进行二次封装,实现图片堆叠三张变五张,图片数量可以多于五张 父组件
<el-carousel
:interval="3000"
type="card"
height="440px"
@change="handleCarouselChange"
ref="carousel"
arrow="never"
indicator-position="none"
>
<Swiper v-for="(item, i) in page8List" :key="i">
<div class="imgBox">
<img class="imgItem" :src="item.bg" alt srcset />
</div>
</Swiper>
</el-carousel>
子组件
<template>
<div
v-show="ready"
class="el-carousel__item"
:class="{
'is-active': active,
'el-carousel__item--card': $parent.type === 'card',
'is-in-stage': inStage,
specialIndex: specialIndex,
'is-hover': hover,
'is-animating': animating,
}"
@click="handleItemClick"
:style="itemStyle"
>
<div v-if="$parent.type === 'card'" v-show="!active" class="el-carousel__mask"></div>
<slot></slot>
</div>
</template>
<script>
import { autoprefixer } from "element-ui/src/utils/util";
const CARD_SCALE = 0.83;
export default {
name: "ElCarouselItem",
props: {
name: String,
label: {
type: [String, Number],
default: ""
}
},
data() {
return {
hover: false,
translate: 0,
scale: 1,
active: false,
ready: false,
inStage: false,
specialIndex: false,
animating: false,
zIndex: 0
};
},
created() {
this.$parent && this.$parent.updateItems();
},
destroyed() {
this.$parent && this.$parent.updateItems();
},
methods: {
processIndex(index, activeIndex, length) {
if (activeIndex === 0 && index === length - 1) {
return -1;
} else if (activeIndex === length - 1 && index === 0) {
return length;
} else if (index < activeIndex - 2 && activeIndex - index >= length / 2) {
let num = length - activeIndex;
if (num <= 3 && 3 - num > index) {
return length + index;
}
return length + 2;
} else if (index < activeIndex - 1 && activeIndex - index >= length / 2) {
return length + 1;
} else if (index > activeIndex + 2 && index - activeIndex >= length / 2) {
if (activeIndex < 3) {
return activeIndex - (length - (index - activeIndex));
}
}
return index;
},
calcCardTranslate(index, activeIndex) {
const parentWidth = this.$parent.$el.offsetWidth;
if (index == activeIndex) {
return parentWidth * 0.28;
} else if (this.inStage) {
let num = index - activeIndex;
if (num > 0) return parentWidth * (0.3 + 0.12 * num);
else return parentWidth * (0.12 * (num + 2));
} else if (index < activeIndex) {
return (-(1 + CARD_SCALE) * parentWidth) / 4;
} else {
return ((3 + CARD_SCALE) * parentWidth) / 4;
}
},
calcTranslate(index, activeIndex, isVertical) {
const distance = this.$parent.$el[
isVertical ? "offsetHeight" : "offsetWidth"
];
return distance * (index - activeIndex);
},
translateItem(index, activeIndex, oldIndex) {
const parentType = this.$parent.type;
const parentDirection = this.parentDirection;
const length = this.$parent.items.length;
if (parentType !== "card" && oldIndex !== undefined) {
this.animating = index === activeIndex || index === oldIndex;
}
index = this.processIndex(index, activeIndex, length);
if (parentType === "card") {
if (parentDirection === "vertical") {
console.warn(
"[Element Warn][Carousel]vertical direction is not supported in card mode"
);
}
this.inStage = Math.round(Math.abs(index - activeIndex)) <= 2;
this.active = index === activeIndex;
this.translate = this.calcCardTranslate(index, activeIndex);
this.zIndex = Math.abs(activeIndex - index);
this.scale = this.active
? 1
: this.inStage
? this.zIndex == 1
? 0.9
: 0.8
: 0.5;
} else {
this.active = index === activeIndex;
const isVertical = parentDirection === "vertical";
this.translate = this.calcTranslate(index, activeIndex, isVertical);
}
this.ready = true;
},
handleItemClick() {
const parent = this.$parent;
if (parent && parent.type === "card") {
const index = parent.items.indexOf(this);
parent.setActiveItem(index);
}
}
},
computed: {
parentDirection() {
return this.$parent.direction;
},
itemStyle() {
const translateType =
this.parentDirection.value === "vertical" ? "translateY" : "translateX";
const value = `${translateType}(${this.translate}px) scale(${this.scale})`;
const style = {
transform: value,
zIndex: 10 - this.zIndex
};
return autoprefixer(style);
}
}
};
</script>
<style scoped>
</style>