Merge pull request #2181 from lisafra/update-carousel
Update carousel component: add loop and radiusDot property
This commit is contained in:
commit
69460a549c
4 changed files with 110 additions and 19 deletions
|
@ -1,10 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Carousel v-model="v1" dots="inside" trigger="hover">
|
<Carousel v-model="v1" dots="inside" trigger="hover" autoplay loop radius-dot>
|
||||||
<Carousel-item>
|
<Carousel-item>
|
||||||
<Card>
|
<div class="demo-carousel">1</div>
|
||||||
<div class="demo-carousel">1</div>
|
|
||||||
</Card>
|
|
||||||
</Carousel-item>
|
</Carousel-item>
|
||||||
<Carousel-item>
|
<Carousel-item>
|
||||||
<div class="demo-carousel">2</div>
|
<div class="demo-carousel">2</div>
|
||||||
|
@ -24,8 +22,8 @@
|
||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
v1: 1
|
v1: 0
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
push () {
|
push () {
|
||||||
|
|
|
@ -27,6 +27,15 @@
|
||||||
mounted () {
|
mounted () {
|
||||||
this.$parent.slotChange();
|
this.$parent.slotChange();
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
width (val) {
|
||||||
|
if (val && this.$parent.loop) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$parent.initCopyTrackDom();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
this.$parent.slotChange();
|
this.$parent.slotChange();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
<Icon type="chevron-left"></Icon>
|
<Icon type="chevron-left"></Icon>
|
||||||
</button>
|
</button>
|
||||||
<div :class="[prefixCls + '-list']">
|
<div :class="[prefixCls + '-list']">
|
||||||
<div :class="[prefixCls + '-track']" :style="trackStyles">
|
<div :class="[prefixCls + '-track', showCopyTrack ? '' : 'higher']" :style="trackStyles" ref="originTrack">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
<div :class="[prefixCls + '-track', showCopyTrack ? 'higher' : '']" :style="copyTrackStyles" ref="copyTrack" v-if="loop">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button :class="arrowClasses" class="right" @click="arrowEvent(1)">
|
<button :class="arrowClasses" class="right" @click="arrowEvent(1)">
|
||||||
<Icon type="chevron-right"></Icon>
|
<Icon type="chevron-right"></Icon>
|
||||||
|
@ -16,7 +18,7 @@
|
||||||
<li :class="[n - 1 === currentIndex ? prefixCls + '-active' : '']"
|
<li :class="[n - 1 === currentIndex ? prefixCls + '-active' : '']"
|
||||||
@click="dotsEvent('click', n - 1)"
|
@click="dotsEvent('click', n - 1)"
|
||||||
@mouseover="dotsEvent('hover', n - 1)">
|
@mouseover="dotsEvent('hover', n - 1)">
|
||||||
<button></button>
|
<button :class="[radiusDot ? 'radius' : '']"></button>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -48,6 +50,10 @@
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 2000
|
default: 2000
|
||||||
},
|
},
|
||||||
|
loop: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
easing: {
|
easing: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'ease'
|
default: 'ease'
|
||||||
|
@ -59,6 +65,10 @@
|
||||||
return oneOf(value, ['inside', 'outside', 'none']);
|
return oneOf(value, ['inside', 'outside', 'none']);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
radiusDot: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
trigger: {
|
trigger: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'click',
|
default: 'click',
|
||||||
|
@ -84,11 +94,16 @@
|
||||||
listWidth: 0,
|
listWidth: 0,
|
||||||
trackWidth: 0,
|
trackWidth: 0,
|
||||||
trackOffset: 0,
|
trackOffset: 0,
|
||||||
|
trackCopyOffset: 0,
|
||||||
|
showCopyTrack: false,
|
||||||
slides: [],
|
slides: [],
|
||||||
slideInstances: [],
|
slideInstances: [],
|
||||||
timer: null,
|
timer: null,
|
||||||
ready: false,
|
ready: false,
|
||||||
currentIndex: this.value
|
currentIndex: this.value,
|
||||||
|
trackIndex: this.value,
|
||||||
|
copyTrackIndex: this.value,
|
||||||
|
hideTrackPos: -1, // 默认左滑
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -100,10 +115,19 @@
|
||||||
trackStyles () {
|
trackStyles () {
|
||||||
return {
|
return {
|
||||||
width: `${this.trackWidth}px`,
|
width: `${this.trackWidth}px`,
|
||||||
transform: `translate3d(-${this.trackOffset}px, 0px, 0px)`,
|
transform: `translate3d(${-this.trackOffset}px, 0px, 0px)`,
|
||||||
transition: `transform 500ms ${this.easing}`
|
transition: `transform 500ms ${this.easing}`
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
copyTrackStyles () {
|
||||||
|
return {
|
||||||
|
width: `${this.trackWidth}px`,
|
||||||
|
transform: `translate3d(${-this.trackCopyOffset}px, 0px, 0px)`,
|
||||||
|
transition: `transform 500ms ${this.easing}`,
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
arrowClasses () {
|
arrowClasses () {
|
||||||
return [
|
return [
|
||||||
`${prefixCls}-arrow`,
|
`${prefixCls}-arrow`,
|
||||||
|
@ -142,6 +166,12 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// copy trackDom
|
||||||
|
initCopyTrackDom () {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.copyTrack.innerHTML = this.$refs.originTrack.innerHTML;
|
||||||
|
});
|
||||||
|
},
|
||||||
updateSlides (init) {
|
updateSlides (init) {
|
||||||
let slides = [];
|
let slides = [];
|
||||||
let index = 1;
|
let index = 1;
|
||||||
|
@ -158,7 +188,6 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
this.slides = slides;
|
this.slides = slides;
|
||||||
|
|
||||||
this.updatePos();
|
this.updatePos();
|
||||||
},
|
},
|
||||||
updatePos () {
|
updatePos () {
|
||||||
|
@ -185,21 +214,57 @@
|
||||||
this.updatePos();
|
this.updatePos();
|
||||||
this.updateOffset();
|
this.updateOffset();
|
||||||
},
|
},
|
||||||
|
updateTrackPos (index) {
|
||||||
|
if (this.showCopyTrack) {
|
||||||
|
this.trackIndex = index;
|
||||||
|
} else {
|
||||||
|
this.copyTrackIndex = index;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateTrackIndex (index) {
|
||||||
|
if (this.showCopyTrack) {
|
||||||
|
this.copyTrackIndex = index;
|
||||||
|
} else {
|
||||||
|
this.trackIndex = index;
|
||||||
|
}
|
||||||
|
},
|
||||||
add (offset) {
|
add (offset) {
|
||||||
let index = this.currentIndex;
|
// 获取单个轨道的图片数
|
||||||
|
let slidesLen = this.slides.length;
|
||||||
|
// 如果是无缝滚动,需要初始化双轨道位置
|
||||||
|
if (this.loop) {
|
||||||
|
if (offset > 0) {
|
||||||
|
// 初始化左滑轨道位置
|
||||||
|
this.hideTrackPos = -1;
|
||||||
|
} else {
|
||||||
|
// 初始化右滑轨道位置
|
||||||
|
this.hideTrackPos = slidesLen;
|
||||||
|
}
|
||||||
|
this.updateTrackPos(this.hideTrackPos);
|
||||||
|
}
|
||||||
|
// 获取当前展示图片的索引值
|
||||||
|
let index = this.showCopyTrack ? this.copyTrackIndex : this.trackIndex;
|
||||||
index += offset;
|
index += offset;
|
||||||
while (index < 0) index += this.slides.length;
|
while (index < 0) index += slidesLen;
|
||||||
index = index % this.slides.length;
|
if (((offset > 0 && index === slidesLen) || (offset < 0 && index === slidesLen - 1)) && this.loop) {
|
||||||
this.currentIndex = index;
|
// 极限值(左滑:当前索引为总图片张数, 右滑:当前索引为总图片张数 - 1)切换轨道
|
||||||
this.$emit('input', index);
|
this.showCopyTrack = !this.showCopyTrack;
|
||||||
|
this.trackIndex += offset;
|
||||||
|
this.copyTrackIndex += offset;
|
||||||
|
} else {
|
||||||
|
if (!this.loop) index = index % this.slides.length;
|
||||||
|
this.updateTrackIndex(index);
|
||||||
|
}
|
||||||
|
this.$emit('input', index === this.slides.length ? 0 : index);
|
||||||
},
|
},
|
||||||
arrowEvent (offset) {
|
arrowEvent (offset) {
|
||||||
this.setAutoplay();
|
this.setAutoplay();
|
||||||
this.add(offset);
|
this.add(offset);
|
||||||
},
|
},
|
||||||
dotsEvent (event, n) {
|
dotsEvent (event, n) {
|
||||||
if (event === this.trigger && this.currentIndex !== n) {
|
let curIndex = this.showCopyTrack ? this.copyTrackIndex : this.trackIndex;
|
||||||
this.currentIndex = n;
|
if (event === this.trigger && curIndex !== n) {
|
||||||
|
this.updateTrackIndex(n);
|
||||||
this.$emit('input', n);
|
this.$emit('input', n);
|
||||||
// Reset autoplay timer when trigger be activated
|
// Reset autoplay timer when trigger be activated
|
||||||
this.setAutoplay();
|
this.setAutoplay();
|
||||||
|
@ -215,7 +280,10 @@
|
||||||
},
|
},
|
||||||
updateOffset () {
|
updateOffset () {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.trackOffset = this.currentIndex * this.listWidth;
|
/* hack: revise copyTrack offset (1px) */
|
||||||
|
let ofs = this.copyTrackIndex > 0 ? -1 : 1;
|
||||||
|
this.trackOffset = this.trackIndex * this.listWidth;
|
||||||
|
this.trackCopyOffset = this.copyTrackIndex * this.listWidth + ofs;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -228,6 +296,11 @@
|
||||||
},
|
},
|
||||||
currentIndex (val, oldVal) {
|
currentIndex (val, oldVal) {
|
||||||
this.$emit('on-change', oldVal, val);
|
this.$emit('on-change', oldVal, val);
|
||||||
|
},
|
||||||
|
trackIndex () {
|
||||||
|
this.updateOffset();
|
||||||
|
},
|
||||||
|
copyTrackIndex () {
|
||||||
this.updateOffset();
|
this.updateOffset();
|
||||||
},
|
},
|
||||||
height () {
|
height () {
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
&.higher {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-item {
|
&-item {
|
||||||
|
@ -159,6 +162,11 @@
|
||||||
color: transparent;
|
color: transparent;
|
||||||
|
|
||||||
transition: all .5s;
|
transition: all .5s;
|
||||||
|
&.radius {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover > button {
|
&:hover > button {
|
||||||
|
@ -168,6 +176,9 @@
|
||||||
&.@{carousel-prefix-cls}-active > button {
|
&.@{carousel-prefix-cls}-active > button {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
|
&.radius{
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue