1、element ui走马灯组件 -- carousel
分析一波源代码:carousel/src/main.vue 文件为 el-carousel文件主要功能carousel/src/item.vue 文件为 el-carousel-item 功能2、carousel/src/main.vue文件详解:
1)、左右button切换按钮<divclass="el-carousel__container":style="{ height: height }"><transition name="carousel-arrow-left"><buttontype="button"v-if="arrow !== 'never'"v-show="arrow === 'always' || hover"@mouseenter="handleButtonEnter('left')"@mouseleave="handleButtonLeave"@click.stop="throttledArrowClick(activeIndex - 1)"class="el-carousel__arrow el-carousel__arrow--left"><i class="el-icon-arrow-left"></i></button></transition><transition name="carousel-arrow-right"><buttontype="button"v-if="arrow !== 'never'"v-show="arrow === 'always' || hover"@mouseenter="handleButtonEnter('right')"@mouseleave="handleButtonLeave"@click.stop="throttledArrowClick(activeIndex + 1)"class="el-carousel__arrow el-carousel__arrow--right"><i class="el-icon-arrow-right"></i></button></transition><slot></slot></div>2)、横向tab切换
<ulclass="el-carousel__indicators"v-if="indicatorPosition !== 'none'":class="{ 'el-carousel__indicators--labels': hasLabel, 'el-carousel__indicators--outside': indicatorPosition === 'outside' || type === 'card' }"><liv-for="(item, index) in items"class="el-carousel__indicator":class="{ 'is-active': index === activeIndex }"@mouseenter="throttledIndicatorHover(index)"@click.stop="handleIndicatorClick(index)"><button class="el-carousel__button"><span v-if="hasLabel">{ { item.label }}</span></button></li></ul>3)关联child ElCarouselItem组件的方式如:我将我的子组件命名为MyElCarouselItem 则为如下updateItems() { this.items = this.options.name === 'MyElCarouselItem');}3、carousel/src/item.vue 文件详解:
1)计算每个CarouselItem 的translate 距离calculateTranslate(index, activeIndex, parentWidth) { if (this.inStage) { return parentWidth * ((2 - CARD_SCALE) * (index - activeIndex) + 1) / 4;} else if (index < activeIndex) { return -(1 + CARD_SCALE) * parentWidth / 4;} else { return (3 + CARD_SCALE) * parentWidth / 4;}}2)CarouselItem 的大小样式确定 以及滚动距离样式确定 translate、scale值
translateItem(index, activeIndex, oldIndex) { const parentWidth = this.el.offsetWidth;const length = this.parent.type !== 'card' && oldIndex !== undefined) { this.animating = index === activeIndex || index === oldIndex;}if (index !== activeIndex && length > 2) { index = this.processIndex(index, activeIndex, length);}if (this.$parent.type === 'card') { this.inStage = Math.round(Math.abs(index - activeIndex)) <= 1;this.active = index === activeIndex;this.translate = this.calculateTranslate(index, activeIndex, parentWidth);this.scale = this.active ? 1 : CARD_SCALE;} else { this.active = index === activeIndex;this.translate = parentWidth * (index - activeIndex);}this.ready = true;}4、个人修改实现5个card展示在前,不全屏展示的效果
12.png
1)各card的大小缩小比率
const CARD_SCALE = 0.9; // 中心Card的左右两边的第一个card大小缩小比例const CARD_SCALE_diff_second = 0.1; //中心Card的左右两边的第二个card大小缩小比例 与中心Card的左右两边的第一个card大小缩小比例差值 ,即中心Card的左右两边的第二个card大小缩小比例为:CARD_SCALE - CARD_SCALE_diff_second2)、计算5个card的移动距离 ,以下写法超过5个会出现切换视觉效果不佳问题
calculateTranslate(index, activeIndex, parentWidth,cardWidth) {const diff = (parentWidth-(1 + 2 * CARD_SCALE + 2* (CARD_SCALE - CARD_SCALE_diff_second)) * cardWidth)/2
if (this.inStage) { if(Math.abs(index - activeIndex) <2){ return diff + ((index - activeIndex +2) *(0 + CARD_SCALE )- CARD_SCALE_diff_second) * cardWidth ; }else if(index - activeIndex <= -2){ return diff ; } return diff + (4 * CARD_SCALE - 2 * CARD_SCALE_diff_second ) * cardWidth; } //方式一: // else if (index < activeIndex) { // return -parentWidth; // } else { // return parentWidth + (diff + (4 * CARD_SCALE - 2 * CARD_SCALE_diff_second ) * cardWidth); // } return diff + (2 * CARD_SCALE - CARD_SCALE_diff_second) * cardWidth; },3)、计算translatetranslateItem(index, activeIndex, oldIndex) { const parentWidth = this.el.offsetWidth;const length = this.el.offsetWidth;if (this.parent.type === 'card') { this.inStage = Math.round(Math.abs(index - activeIndex)) <= 3;this.active = index === activeIndex;this.translate = this.calculateTranslate(index, activeIndex, parentWidth,cardWidth);this.scale = this.active ? 1 : (Math.abs(index - activeIndex) >= 2)? (CARD_SCALE -CARD_SCALE_diff_second ) : (CARD_SCALE);this.outCard = (Math.abs(index - activeIndex) >= 2)? true : false;} else { this.active = index === activeIndex;this.translate = parentWidth * (index - activeIndex);}this.ready = true;},