vue Element UI走马灯组件重写

1、element ui走马灯组件 -- carousel
分析一波源代码:
carousel/src/main.vue 文件为 el-carousel文件主要功能
carousel/src/item.vue 文件为 el-carousel-item 功能

2、carousel/src/main.vue文件详解:
1)、左右button切换按钮
<div
class="el-carousel__container"
:style="{ height: height }">
<transition name="carousel-arrow-left">
<button
type="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">
<button
type="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切换
<ul
class="el-carousel__indicators"
v-if="indicatorPosition !== 'none'"
:class="{ 'el-carousel__indicators--labels': hasLabel, 'el-carousel__indicators--outside': indicatorPosition === 'outside' || type === 'card' }">
<li
v-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.children.filter(child => child.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.parent.el.offsetWidth;
const length = this.parent.items.length; if (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_second

2)、计算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)、计算translate
translateItem(index, activeIndex, oldIndex) {
const parentWidth = this.parent.el.offsetWidth;
const length = this.parent.items.length; const cardWidth = this.el.offsetWidth;
if (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)) <= 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;
},

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 好姐妹夫妇俩是爱国青年,积极响应国家号召,生了二胎,儿女双全了。祝福、羡慕之余回想起了那段既期待又害怕,既幸福又痛...
    盈盈她说阅读 224评论 0 0
  • 看了采访严歌苓的一篇文章,有句话太打动我: “不管什么时候,都要做一个不凑合不打折不便宜不糟糕的好姑娘。” 这真是...
    汇悦谈情绪管理阅读 148评论 0 0
  • 小镇共有四条街,南北两条,东西两条。原来104国道穿镇而过,前几年绕镇西去了,老国道也就变成人车混流的街道了。这样...
    刨泉之马阅读 253评论 0 0
  • 点击立即阅读:笔若派|朦胧诗_诗歌精选集© 文/笔若看见佛储备金子众人失去的粮食和生命都将是你光滑的躯体你有你死去...
    笔若阅读 535评论 8 28