用過Element Carousel 組件的 應該都知道 ,他只能顯示3個item, 而沒有提供顯示數量設置的屬性,那如果想要顯示多個,就要來改下他的源碼,一起看下吧!
原本樣式:
改動後:
首先在瀏覽器裏先看下他的樣式:
首先我們將隱藏的item 顯示出來 發現他是這個樣子的
我們會發現 他會在左面後者右面有兩個item 是重疊的 其實不重疊 直接就可以用啦 哈哈 我們就在這個基礎上面改就好了!
下面來看下代碼: 首先carousel組件在element-ui/packages/carousel 就可以找到 主要是main.vue和item.vue兩個文件
main.vue 這裏不需要動,只需要改item.vue就可以,先看下item.vue的代碼:
整個的處理主要有三個變量
1. index : 每個item的原本索引值
2. activeIndex : 當前顯示item的索引值 就是比例最大的那個
3. length: item的數量
下面看下 item.vue裏面的方法:
1. 這個方法是根據item的index和當前的activeIndex 以及 length 去重新排序item的位置的一個方法
2. 這個是在上面的方法之後,計算已經排序好的每個 item 的 偏移量
3. 再來看下這個方法 (代碼中註釋說明)
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;
}
if (index !== activeIndex && length > 2 && this.$parent.loop) {
// 這裏調用上面第一個方法 計算每個item應該在的位置
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)) <= 1; // 這裏變量用來判斷class的 當前顯示的和左右兩個爲true 提升了z-index 等級
this.active = index === activeIndex; // 這個變量是用來判斷當前主要展示的item 給了一個class z-index 等級最高
this.translate = this.calcCardTranslate(index, activeIndex); // 這裏調用上面第二個方法 得到每個位置item的偏移量
this.scale = this.active ? 1 : CARD_SCALE;
} else {
this.active = index === activeIndex;
const isVertical = parentDirection === 'vertical';
this.translate = this.calcTranslate(index, activeIndex, isVertical);
}
this.ready = true;
},
Ok,下面是我修改後的 item.vue 完整代碼
<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
};
},
methods: {
processIndex(index, activeIndex, length) {
if(activeIndex == 0) {
return index==1?1:index==2?2:index==3?-3:index==4?-2:index==5?-1:0
}
if(activeIndex == 1) {
return index==2?1:index==3?2:index==4?-3:index==5?-2:index==0?-1:0
}
if(activeIndex == 2) {
return index==3?1:index==4?2:index==5?-3:index==0?-2:index==1?-1:0
}
if(activeIndex == 3) {
return index==4?1:index==5?2:index==0?-3:index==1?-2:index==2?-1:0
}
if(activeIndex == 4) {
return index==5?1:index==0?2:index==1?-3:index==2?-2:index==3?-1:0
}
if(activeIndex == 5) {
return index==0?1:index==1?2:index==2?-3:index==3?-2:index==4?-1:0
}
},
calcCardTranslate(index, activeIndex) {
return index * 80 * 2
},
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)) <= 1;
this.specialIndex = Math.round(Math.abs(index)) >= 3;
this.active = index === 0;
this.translate = this.calcCardTranslate(index, activeIndex);
this.scale = Math.abs(index)==0 ? 1 : Math.abs(index)==1? 0.83 : Math.abs(index)==2? 0.73 : Math.abs(index)==3? 0.65 : 0.58;
} 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 === 'vertical' ? 'translateY' : 'translateX';
const value = `${translateType}(${ this.translate }px) scale(${ this.scale })`;
const style = {
transform: value
};
return autoprefixer(style);
}
},
created() {
this.$parent && this.$parent.updateItems();
},
destroyed() {
this.$parent && this.$parent.updateItems();
}
};
</script>
<style>
.el-carousel__arrow--left {
left: -426px
}
.el-carousel__arrow--right {
right: -25px;
}
.el-carousel__item {
cursor: pointer;
z-index: 1;
}
.el-carousel__item--card.is-in-stage {
z-index: 2;
}
.el-carousel__item--card.is-active {
z-index: 3;
}
.specialIndex{
z-index: 0
}
</style>
主要就是在上面提到的三個方法上面做了改動,我只顯示六張,所以就是按照顯示6張 寫死的值,懶得計算啦 哈哈哈 但是大致思路就是這樣 如果顯示數量不一樣 數值稍作改動就可以啦!