结构
以下的element官方标准的调用方式。其实调用起来很简单,初学vue就能看能看懂。
<el-carousel trigger="click" height="150px">
<el-carousel-item v-for="item in 4" :key="item">
<h3 class="small">{{ item }}</h3>
</el-carousel-item>
</el-carousel>
main.vue
以下的main.vue源码
<div
:class="carouselClasses"
@mouseenter.stop="handleMouseEnter"
@mouseleave.stop="handleMouseLeave">
<div
class="el-carousel__container"
:style="{ height: height }">
<transition
v-if="arrowDisplay"
name="carousel-arrow-left">
<button
type="button"
v-show="(arrow === 'always' || hover) && (loop || activeIndex > 0)"
@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
v-if="arrowDisplay"
name="carousel-arrow-right">
<button
type="button"
v-show="(arrow === 'always' || hover) && (loop || activeIndex < items.length - 1)"
@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>
<ul
v-if="indicatorPosition !== 'none'"
:class="indicatorsClasses">
<li
v-for="(item, index) in items"
:key="index"
:class="[
'el-carousel__indicator',
'el-carousel__indicator--' + direction,
{ '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>
</div>
@event.stop 阻止事件冒泡
throttle 这个是 节流函数,在很多场景都需要用,element单独从npm引入包,我们可以点开学习一下,在之后的项目实战中,肯定会多遇到。其实要注意就是this的改变,callbak.apply(self, args);
以下的精简过后的源码
throttle: 节流函数 (下一次函数执行与上一次函数执行的时间间隔,控制在一定范围内)
function throttle(delay, callbak) {
let timeoutID;
let lastExec = 0; //上一次执行时间
function wrapper() {
const self = this;
const args = arguments;
const elapsed = Number(new Date()) - lastExec; //执行函数与上一次的时间间隔
function exec() {
lastExec = Number(new Date());
callbak.apply(self, args);
}
clearTimeout(timeoutID);
if(elapsed > delay) {
exec();
}else{
timeoutID = setTimeout(exec, delay- elapsed);
}
}
return wrapper
}
item.vue
<div
v-show="ready"
class="el-carousel__item"
:class="{
'is-active': active,
'el-carousel__item--card': $parent.type === 'card',
'is-in-stage': inStage,
'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>
走马灯卡片切换的核心控制 itemStyle。其实实质就是通过css3 transform 平移实现的。
扩展一下,transform 代表“转变” 包含 rotate() 旋转 / skew() 倾斜 / scale() 缩放 / translate() 平移 这几种,另外每一种有X,Y之分 。
transition代表“过度效果” ,如果没有过度效果,平移就是尴尬的,看不出来效果。加了transition就不一样了。
transition: transform .4s ease-in-out;
事例:如果让某个元素做平移30个像素。
transform: translateX(30px);
-wekit-transform: translateX(30px);
-moz-transform: translateX(30px);
后边也可以继续叠加属性 transform: translateX(30px) scale(0.83)
itemStyle() {
const translateType = this.parentDirection === 'vertical' ? 'translateY' : 'translateX';
const value = `${translateType}(${ this.translate }px) scale(${ this.scale })`;
const style = {
transform: value
};
return autoprefixer(style);
}
代码不多就是根据方向判断,拼接平移的语句,autoprefixer是浏览器前缀,用于兼容浏览器的。
总结
1. 样式变量
:style="{height: height}"
:class="['class1','class2', {'is_active' ? true}]"