mirror of https://github.com/ElemeFE/element
Carousel: add direction attribute and support vertical direction (#15122)
parent
5425dc69fe
commit
2a65c9df7e
|
@ -3,7 +3,7 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-right: solid 1px #eff2f6;
|
border-right: solid 1px #eff2f6;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 50%;
|
width: 49%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
|
@ -27,6 +27,14 @@
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
line-height: 300px;
|
line-height: 300px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
&.small {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 150px;
|
||||||
|
}
|
||||||
|
&.medium {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 200px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&:nth-child(2n) {
|
&:nth-child(2n) {
|
||||||
background-color: #99a9bf;
|
background-color: #99a9bf;
|
||||||
|
@ -36,12 +44,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.demo-carousel .small h3 {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 150px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.demo-carousel .medium h3 {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 200px;
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ Loop a series of images or texts in a limited space
|
||||||
<span class="demonstration">Switch when indicator is hovered (default)</span>
|
<span class="demonstration">Switch when indicator is hovered (default)</span>
|
||||||
<el-carousel height="150px">
|
<el-carousel height="150px">
|
||||||
<el-carousel-item v-for="item in 4" :key="item">
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="small">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,7 @@ Loop a series of images or texts in a limited space
|
||||||
<span class="demonstration">Switch when indicator is clicked</span>
|
<span class="demonstration">Switch when indicator is clicked</span>
|
||||||
<el-carousel trigger="click" height="150px">
|
<el-carousel trigger="click" height="150px">
|
||||||
<el-carousel-item v-for="item in 4" :key="item">
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="small">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,7 +122,7 @@ When a page is wide enough but has limited height, you can activate card mode fo
|
||||||
<template>
|
<template>
|
||||||
<el-carousel :interval="4000" type="card" height="200px">
|
<el-carousel :interval="4000" type="card" height="200px">
|
||||||
<el-carousel-item v-for="item in 6" :key="item">
|
<el-carousel-item v-for="item in 6" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="medium">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</template>
|
</template>
|
||||||
|
@ -147,6 +147,38 @@ When a page is wide enough but has limited height, you can activate card mode fo
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
By default, `direction` is `horizontal`. Let carousel be displayed in the vertical direction by setting `direction` to `vertical`.
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<el-carousel height="200px" direction="vertical" :autoplay="false">
|
||||||
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
|
<h3 class="medium">{{ item }}</h3>
|
||||||
|
</el-carousel-item>
|
||||||
|
</el-carousel>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.el-carousel__item h3 {
|
||||||
|
color: #475669;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.75;
|
||||||
|
line-height: 200px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-carousel__item:nth-child(2n) {
|
||||||
|
background-color: #99a9bf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-carousel__item:nth-child(2n+1) {
|
||||||
|
background-color: #d3dce6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### Carousel Attributes
|
### Carousel Attributes
|
||||||
| Attribute | Description | Type | Accepted Values | Default |
|
| Attribute | Description | Type | Accepted Values | Default |
|
||||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||||
|
@ -159,6 +191,7 @@ When a page is wide enough but has limited height, you can activate card mode fo
|
||||||
| arrow | when arrows are shown | string | always/hover/never | hover |
|
| arrow | when arrows are shown | string | always/hover/never | hover |
|
||||||
| type | type of the Carousel | string | card | — |
|
| type | type of the Carousel | string | card | — |
|
||||||
| loop | display the items in loop | boolean | - | true |
|
| loop | display the items in loop | boolean | - | true |
|
||||||
|
| direction | display direction | string | horizontal/vertical | horizontal |
|
||||||
|
|
||||||
### Carousel Events
|
### Carousel Events
|
||||||
| Event Name | Description | Parameters |
|
| Event Name | Description | Parameters |
|
||||||
|
|
|
@ -12,7 +12,7 @@ Presenta una serie de imágenes o textos en un espacio limitado
|
||||||
<span class="demonstration">Switch when indicator is hovered (default)</span>
|
<span class="demonstration">Switch when indicator is hovered (default)</span>
|
||||||
<el-carousel height="150px">
|
<el-carousel height="150px">
|
||||||
<el-carousel-item v-for="item in 4" :key="item">
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="small">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,7 +20,7 @@ Presenta una serie de imágenes o textos en un espacio limitado
|
||||||
<span class="demonstration">Switch when indicator is clicked</span>
|
<span class="demonstration">Switch when indicator is clicked</span>
|
||||||
<el-carousel trigger="click" height="150px">
|
<el-carousel trigger="click" height="150px">
|
||||||
<el-carousel-item v-for="item in 4" :key="item">
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="small">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -126,7 +126,7 @@ Cuando una página es suficientemente ancha pero tiene una altura limitada, pued
|
||||||
<template>
|
<template>
|
||||||
<el-carousel :interval="4000" type="card" height="200px">
|
<el-carousel :interval="4000" type="card" height="200px">
|
||||||
<el-carousel-item v-for="item in 6" :key="item">
|
<el-carousel-item v-for="item in 6" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="medium">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</template>
|
</template>
|
||||||
|
@ -151,6 +151,38 @@ Cuando una página es suficientemente ancha pero tiene una altura limitada, pued
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
By default, `direction` is `horizontal`. Let carousel be displayed in the vertical direction by setting `direction` to `vertical`.
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<el-carousel height="200px" direction="vertical" :autoplay="false">
|
||||||
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
|
<h3 class="medium">{{ item }}</h3>
|
||||||
|
</el-carousel-item>
|
||||||
|
</el-carousel>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.el-carousel__item h3 {
|
||||||
|
color: #475669;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.75;
|
||||||
|
line-height: 200px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-carousel__item:nth-child(2n) {
|
||||||
|
background-color: #99a9bf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-carousel__item:nth-child(2n+1) {
|
||||||
|
background-color: #d3dce6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### Atributos de Carousel
|
### Atributos de Carousel
|
||||||
| Atributo | Descripcion | Tipo | Valores aceptados | Por defecto |
|
| Atributo | Descripcion | Tipo | Valores aceptados | Por defecto |
|
||||||
| ------------------ | ---------------------------------------- | ------- | ------------------ | ----------- |
|
| ------------------ | ---------------------------------------- | ------- | ------------------ | ----------- |
|
||||||
|
@ -162,7 +194,8 @@ Cuando una página es suficientemente ancha pero tiene una altura limitada, pued
|
||||||
| indicator-position | Posición del indicador de paginación | string | outside/none | — |
|
| indicator-position | Posición del indicador de paginación | string | outside/none | — |
|
||||||
| arrow | Cuando se muestran las flechas | string | always/hover/never | hover |
|
| arrow | Cuando se muestran las flechas | string | always/hover/never | hover |
|
||||||
| type | Tipo de carrusel | string | card | — |
|
| type | Tipo de carrusel | string | card | — |
|
||||||
| loop | Si se muestra cíclicamente | boolean | — | true |
|
| loop | Si se muestra cíclicamente | boolean | — | true |
|
||||||
|
| direction | display direction | string | horizontal/vertical| horizontal |
|
||||||
|
|
||||||
### Eventos de Carousel
|
### Eventos de Carousel
|
||||||
| Nombre evento | Descripción | Parametros |
|
| Nombre evento | Descripción | Parametros |
|
||||||
|
|
|
@ -11,7 +11,7 @@ Affiche en boucle une série d'images ou de textes dans un espace limité.
|
||||||
<span class="demonstration">Défile quand la souris passe sur l'indicateur (défaut)</span>
|
<span class="demonstration">Défile quand la souris passe sur l'indicateur (défaut)</span>
|
||||||
<el-carousel height="150px">
|
<el-carousel height="150px">
|
||||||
<el-carousel-item v-for="item in 4" :key="item">
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="small">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,7 @@ Affiche en boucle une série d'images ou de textes dans un espace limité.
|
||||||
<span class="demonstration">Défile quand on clique sur l'indicateur</span>
|
<span class="demonstration">Défile quand on clique sur l'indicateur</span>
|
||||||
<el-carousel trigger="click" height="150px">
|
<el-carousel trigger="click" height="150px">
|
||||||
<el-carousel-item v-for="item in 4" :key="item">
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="small">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,7 +122,7 @@ Quand la page est suffisement large mais avec une hauteur limitée, vous pouvez
|
||||||
<template>
|
<template>
|
||||||
<el-carousel :interval="4000" type="card" height="200px">
|
<el-carousel :interval="4000" type="card" height="200px">
|
||||||
<el-carousel-item v-for="item in 6" :key="item">
|
<el-carousel-item v-for="item in 6" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="medium">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</template>
|
</template>
|
||||||
|
@ -147,6 +147,38 @@ Quand la page est suffisement large mais avec une hauteur limitée, vous pouvez
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
By default, `direction` is `horizontal`. Let carousel be displayed in the vertical direction by setting `direction` to `vertical`.
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<el-carousel height="200px" direction="vertical" :autoplay="false">
|
||||||
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
|
<h3 class="medium">{{ item }}</h3>
|
||||||
|
</el-carousel-item>
|
||||||
|
</el-carousel>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.el-carousel__item h3 {
|
||||||
|
color: #475669;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.75;
|
||||||
|
line-height: 200px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-carousel__item:nth-child(2n) {
|
||||||
|
background-color: #99a9bf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-carousel__item:nth-child(2n+1) {
|
||||||
|
background-color: #d3dce6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### Attributs du Carousel
|
### Attributs du Carousel
|
||||||
| Attribut | Description | Type | Valeurs acceptées | Défaut |
|
| Attribut | Description | Type | Valeurs acceptées | Défaut |
|
||||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||||
|
@ -159,6 +191,7 @@ Quand la page est suffisement large mais avec une hauteur limitée, vous pouvez
|
||||||
| arrow | Détermine quand les flèches sont affichés. | string | always/hover/never | hover |
|
| arrow | Détermine quand les flèches sont affichés. | string | always/hover/never | hover |
|
||||||
| type | Type du carousel. | string | card | — |
|
| type | Type du carousel. | string | card | — |
|
||||||
| loop | Affiche les éléments en boucle. | boolean | - | true |
|
| loop | Affiche les éléments en boucle. | boolean | - | true |
|
||||||
|
| direction | display direction | string | horizontal/vertical | horizontal |
|
||||||
|
|
||||||
### Évènements du Carousel
|
### Évènements du Carousel
|
||||||
| Nom | Description | Paramètres |
|
| Nom | Description | Paramètres |
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<span class="demonstration">默认 Hover 指示器触发</span>
|
<span class="demonstration">默认 Hover 指示器触发</span>
|
||||||
<el-carousel height="150px">
|
<el-carousel height="150px">
|
||||||
<el-carousel-item v-for="item in 4" :key="item">
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="small">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<span class="demonstration">Click 指示器触发</span>
|
<span class="demonstration">Click 指示器触发</span>
|
||||||
<el-carousel trigger="click" height="150px">
|
<el-carousel trigger="click" height="150px">
|
||||||
<el-carousel-item v-for="item in 4" :key="item">
|
<el-carousel-item v-for="item in 4" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="small">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,7 +122,39 @@
|
||||||
<template>
|
<template>
|
||||||
<el-carousel :interval="4000" type="card" height="200px">
|
<el-carousel :interval="4000" type="card" height="200px">
|
||||||
<el-carousel-item v-for="item in 6" :key="item">
|
<el-carousel-item v-for="item in 6" :key="item">
|
||||||
<h3>{{ item }}</h3>
|
<h3 class="medium">{{ item }}</h3>
|
||||||
|
</el-carousel-item>
|
||||||
|
</el-carousel>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.el-carousel__item h3 {
|
||||||
|
color: #475669;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.75;
|
||||||
|
line-height: 200px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-carousel__item:nth-child(2n) {
|
||||||
|
background-color: #99a9bf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-carousel__item:nth-child(2n+1) {
|
||||||
|
background-color: #d3dce6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 方向
|
||||||
|
默认情况下,`direction` 为 `horizontal`。通过设置 `direction` 为 `vertical` 来让走马灯在垂直方向上显示。
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<el-carousel height="200px" direction="vertical" :autoplay="false">
|
||||||
|
<el-carousel-item v-for="item in 3" :key="item">
|
||||||
|
<h3 class="medium">{{ item }}</h3>
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</template>
|
</template>
|
||||||
|
@ -159,6 +191,7 @@
|
||||||
| arrow | 切换箭头的显示时机 | string | always/hover/never | hover |
|
| arrow | 切换箭头的显示时机 | string | always/hover/never | hover |
|
||||||
| type | 走马灯的类型 | string | card | — |
|
| type | 走马灯的类型 | string | card | — |
|
||||||
| loop | 是否循环显示 | boolean | - | true |
|
| loop | 是否循环显示 | boolean | - | true |
|
||||||
|
| direction | 走马灯展示的方向 | string | horizontal/vertical | horizontal |
|
||||||
|
|
||||||
### Carousel Events
|
### Carousel Events
|
||||||
| 事件名称 | 说明 | 回调参数 |
|
| 事件名称 | 说明 | 回调参数 |
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
'is-animating': animating
|
'is-animating': animating
|
||||||
}"
|
}"
|
||||||
@click="handleItemClick"
|
@click="handleItemClick"
|
||||||
:style="{
|
:style="itemStyle">
|
||||||
msTransform: `translateX(${ translate }px) scale(${ scale })`,
|
|
||||||
webkitTransform: `translateX(${ translate }px) scale(${ scale })`,
|
|
||||||
transform: `translateX(${ translate }px) scale(${ scale })`
|
|
||||||
}">
|
|
||||||
<div
|
<div
|
||||||
v-if="$parent.type === 'card'"
|
v-if="$parent.type === 'card'"
|
||||||
v-show="!active"
|
v-show="!active"
|
||||||
|
@ -25,6 +21,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { autoprefixer } from 'element-ui/src/utils/util';
|
||||||
const CARD_SCALE = 0.83;
|
const CARD_SCALE = 0.83;
|
||||||
export default {
|
export default {
|
||||||
name: 'ElCarouselItem',
|
name: 'ElCarouselItem',
|
||||||
|
@ -63,7 +60,8 @@
|
||||||
return index;
|
return index;
|
||||||
},
|
},
|
||||||
|
|
||||||
calculateTranslate(index, activeIndex, parentWidth) {
|
calcCardTranslate(index, activeIndex) {
|
||||||
|
const parentWidth = this.$parent.$el.offsetWidth;
|
||||||
if (this.inStage) {
|
if (this.inStage) {
|
||||||
return parentWidth * ((2 - CARD_SCALE) * (index - activeIndex) + 1) / 4;
|
return parentWidth * ((2 - CARD_SCALE) * (index - activeIndex) + 1) / 4;
|
||||||
} else if (index < activeIndex) {
|
} else if (index < activeIndex) {
|
||||||
|
@ -73,23 +71,33 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
calcTranslate(index, activeIndex, isVertical) {
|
||||||
|
const distance = this.$parent.$el[isVertical ? 'offsetHeight' : 'offsetWidth'];
|
||||||
|
return distance * (index - activeIndex);
|
||||||
|
},
|
||||||
|
|
||||||
translateItem(index, activeIndex, oldIndex) {
|
translateItem(index, activeIndex, oldIndex) {
|
||||||
const parentWidth = this.$parent.$el.offsetWidth;
|
const parentType = this.$parent.type;
|
||||||
|
const parentDirection = this.parentDirection;
|
||||||
const length = this.$parent.items.length;
|
const length = this.$parent.items.length;
|
||||||
if (this.$parent.type !== 'card' && oldIndex !== undefined) {
|
if (parentType !== 'card' && oldIndex !== undefined) {
|
||||||
this.animating = index === activeIndex || index === oldIndex;
|
this.animating = index === activeIndex || index === oldIndex;
|
||||||
}
|
}
|
||||||
if (index !== activeIndex && length > 2 && this.$parent.loop) {
|
if (index !== activeIndex && length > 2 && this.$parent.loop) {
|
||||||
index = this.processIndex(index, activeIndex, length);
|
index = this.processIndex(index, activeIndex, length);
|
||||||
}
|
}
|
||||||
if (this.$parent.type === 'card') {
|
if (parentType === 'card') {
|
||||||
|
if (parentDirection === 'vertical') {
|
||||||
|
console.warn('[Element Warn][Carousel]vertical directionis not supported in card mode');
|
||||||
|
}
|
||||||
this.inStage = Math.round(Math.abs(index - activeIndex)) <= 1;
|
this.inStage = Math.round(Math.abs(index - activeIndex)) <= 1;
|
||||||
this.active = index === activeIndex;
|
this.active = index === activeIndex;
|
||||||
this.translate = this.calculateTranslate(index, activeIndex, parentWidth);
|
this.translate = this.calcCardTranslate(index, activeIndex);
|
||||||
this.scale = this.active ? 1 : CARD_SCALE;
|
this.scale = this.active ? 1 : CARD_SCALE;
|
||||||
} else {
|
} else {
|
||||||
this.active = index === activeIndex;
|
this.active = index === activeIndex;
|
||||||
this.translate = parentWidth * (index - activeIndex);
|
const isVertical = parentDirection === 'vertical';
|
||||||
|
this.translate = this.calcTranslate(index, activeIndex, isVertical);
|
||||||
}
|
}
|
||||||
this.ready = true;
|
this.ready = true;
|
||||||
},
|
},
|
||||||
|
@ -103,6 +111,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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() {
|
created() {
|
||||||
this.$parent && this.$parent.updateItems();
|
this.$parent && this.$parent.updateItems();
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="el-carousel"
|
:class="carouselClasses"
|
||||||
:class="{ 'el-carousel--card': type === 'card' }"
|
|
||||||
@mouseenter.stop="handleMouseEnter"
|
@mouseenter.stop="handleMouseEnter"
|
||||||
@mouseleave.stop="handleMouseLeave">
|
@mouseleave.stop="handleMouseLeave">
|
||||||
<div
|
<div
|
||||||
class="el-carousel__container"
|
class="el-carousel__container"
|
||||||
:style="{ height: height }">
|
:style="{ height: height }">
|
||||||
<transition name="carousel-arrow-left">
|
<transition
|
||||||
|
v-if="arrowDisplay"
|
||||||
|
name="carousel-arrow-left">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
v-if="arrow !== 'never'"
|
|
||||||
v-show="(arrow === 'always' || hover) && (loop || activeIndex > 0)"
|
v-show="(arrow === 'always' || hover) && (loop || activeIndex > 0)"
|
||||||
@mouseenter="handleButtonEnter('left')"
|
@mouseenter="handleButtonEnter('left')"
|
||||||
@mouseleave="handleButtonLeave"
|
@mouseleave="handleButtonLeave"
|
||||||
|
@ -19,10 +19,11 @@
|
||||||
<i class="el-icon-arrow-left"></i>
|
<i class="el-icon-arrow-left"></i>
|
||||||
</button>
|
</button>
|
||||||
</transition>
|
</transition>
|
||||||
<transition name="carousel-arrow-right">
|
<transition
|
||||||
|
v-if="arrowDisplay"
|
||||||
|
name="carousel-arrow-right">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
v-if="arrow !== 'never'"
|
|
||||||
v-show="(arrow === 'always' || hover) && (loop || activeIndex < items.length - 1)"
|
v-show="(arrow === 'always' || hover) && (loop || activeIndex < items.length - 1)"
|
||||||
@mouseenter="handleButtonEnter('right')"
|
@mouseenter="handleButtonEnter('right')"
|
||||||
@mouseleave="handleButtonLeave"
|
@mouseleave="handleButtonLeave"
|
||||||
|
@ -34,16 +35,20 @@
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
class="el-carousel__indicators"
|
|
||||||
v-if="indicatorPosition !== 'none'"
|
v-if="indicatorPosition !== 'none'"
|
||||||
:class="{ 'el-carousel__indicators--labels': hasLabel, 'el-carousel__indicators--outside': indicatorPosition === 'outside' || type === 'card' }">
|
:class="indicatorsClasses">
|
||||||
<li
|
<li
|
||||||
v-for="(item, index) in items"
|
v-for="(item, index) in items"
|
||||||
class="el-carousel__indicator"
|
:key="index"
|
||||||
:class="{ 'is-active': index === activeIndex }"
|
:class="[
|
||||||
|
'el-carousel__indicator',
|
||||||
|
'el-carousel__indicator--' + direction,
|
||||||
|
{ 'is-active': index === activeIndex }]"
|
||||||
@mouseenter="throttledIndicatorHover(index)"
|
@mouseenter="throttledIndicatorHover(index)"
|
||||||
@click.stop="handleIndicatorClick(index)">
|
@click.stop="handleIndicatorClick(index)">
|
||||||
<button class="el-carousel__button"><span v-if="hasLabel">{{ item.label }}</span></button>
|
<button class="el-carousel__button">
|
||||||
|
<span v-if="hasLabel">{{ item.label }}</span>
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,6 +92,13 @@ export default {
|
||||||
loop: {
|
loop: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
direction: {
|
||||||
|
type: String,
|
||||||
|
default: 'horizontal',
|
||||||
|
validator(val) {
|
||||||
|
return ['horizontal', 'vertical'].indexOf(val) !== -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -101,8 +113,31 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
arrowDisplay() {
|
||||||
|
return this.arrow !== 'never' && this.direction !== 'vertical';
|
||||||
|
},
|
||||||
|
|
||||||
hasLabel() {
|
hasLabel() {
|
||||||
return this.items.some(item => item.label.toString().length > 0);
|
return this.items.some(item => item.label.toString().length > 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
carouselClasses() {
|
||||||
|
const classes = ['el-carousel', 'el-carousel--' + this.direction];
|
||||||
|
if (this.type === 'card') {
|
||||||
|
classes.push('el-carousel--card');
|
||||||
|
}
|
||||||
|
return classes;
|
||||||
|
},
|
||||||
|
|
||||||
|
indicatorsClasses() {
|
||||||
|
const classes = ['el-carousel__indicators', 'el-carousel__indicators--' + this.direction];
|
||||||
|
if (this.hasLabel) {
|
||||||
|
classes.push('el-carousel__indicators--labels');
|
||||||
|
}
|
||||||
|
if (this.indicatorPosition === 'outside' || this.type === 'card') {
|
||||||
|
classes.push('el-carousel__indicators--outside');
|
||||||
|
}
|
||||||
|
return classes;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -149,6 +184,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleButtonEnter(arrow) {
|
handleButtonEnter(arrow) {
|
||||||
|
if (this.direction === 'vertical') return;
|
||||||
this.items.forEach((item, index) => {
|
this.items.forEach((item, index) => {
|
||||||
if (arrow === this.itemInStage(item, index)) {
|
if (arrow === this.itemInStage(item, index)) {
|
||||||
item.hover = true;
|
item.hover = true;
|
||||||
|
@ -157,6 +193,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleButtonLeave() {
|
handleButtonLeave() {
|
||||||
|
if (this.direction === 'vertical') return;
|
||||||
this.items.forEach(item => {
|
this.items.forEach(item => {
|
||||||
item.hover = false;
|
item.hover = false;
|
||||||
});
|
});
|
||||||
|
@ -201,7 +238,6 @@ export default {
|
||||||
}
|
}
|
||||||
index = Number(index);
|
index = Number(index);
|
||||||
if (isNaN(index) || index !== Math.floor(index)) {
|
if (isNaN(index) || index !== Math.floor(index)) {
|
||||||
process.env.NODE_ENV !== 'production' &&
|
|
||||||
console.warn('[Element Warn][Carousel]index must be an integer.');
|
console.warn('[Element Warn][Carousel]index must be an integer.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,16 @@
|
||||||
@import "common/var";
|
@import "common/var";
|
||||||
|
|
||||||
@include b(carousel) {
|
@include b(carousel) {
|
||||||
overflow-x: hidden;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@include m(horizontal) {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include m(vertical) {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
@include e(container) {
|
@include e(container) {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
|
@ -49,13 +56,22 @@
|
||||||
@include e(indicators) {
|
@include e(indicators) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
z-index: #{$--index-normal + 1};
|
z-index: #{$--index-normal + 1};
|
||||||
|
|
||||||
|
@include m(horizontal) {
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include m(vertical) {
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
@include m(outside) {
|
@include m(outside) {
|
||||||
bottom: #{$--carousel-indicator-height + $--carousel-indicator-padding-vertical * 2};
|
bottom: #{$--carousel-indicator-height + $--carousel-indicator-padding-vertical * 2};
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -90,15 +106,26 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(indicator) {
|
@include e(indicator) {
|
||||||
display: inline-block;
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
padding: $--carousel-indicator-padding-vertical $--carousel-indicator-padding-horizontal;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover button {
|
&:hover button {
|
||||||
opacity: 0.72;
|
opacity: 0.72;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include m(horizontal) {
|
||||||
|
display: inline-block;
|
||||||
|
padding: $--carousel-indicator-padding-vertical $--carousel-indicator-padding-horizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include m(vertical) {
|
||||||
|
padding: $--carousel-indicator-padding-horizontal $--carousel-indicator-padding-vertical;
|
||||||
|
.el-carousel__button {
|
||||||
|
width: $--carousel-indicator-height;
|
||||||
|
height: #{$--carousel-indicator-width / 2};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@include when(active) {
|
@include when(active) {
|
||||||
button {
|
button {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
|
@ -120,3 +120,18 @@ export const isIE = function() {
|
||||||
export const isEdge = function() {
|
export const isEdge = function() {
|
||||||
return !Vue.prototype.$isServer && navigator.userAgent.indexOf('Edge') > -1;
|
return !Vue.prototype.$isServer && navigator.userAgent.indexOf('Edge') > -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const autoprefixer = function(style) {
|
||||||
|
if (typeof style !== 'object') return style;
|
||||||
|
const rules = ['transform', 'transition', 'animation'];
|
||||||
|
const prefixes = ['ms-', 'webkit-'];
|
||||||
|
rules.forEach(rule => {
|
||||||
|
const value = style[rule];
|
||||||
|
if (rule && value) {
|
||||||
|
prefixes.forEach(prefix => {
|
||||||
|
style[prefix + rule] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
|
@ -10,12 +10,13 @@ describe('Carousel', () => {
|
||||||
vm = createVue({
|
vm = createVue({
|
||||||
template: `
|
template: `
|
||||||
<div>
|
<div>
|
||||||
<el-carousel>
|
<el-carousel ref="carousel">
|
||||||
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
|
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
});
|
});
|
||||||
|
expect(vm.$refs.carousel.direction).to.be.equal('horizontal');
|
||||||
expect(vm.$el.querySelectorAll('.el-carousel__item').length).to.equal(3);
|
expect(vm.$el.querySelectorAll('.el-carousel__item').length).to.equal(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -256,5 +257,21 @@ describe('Carousel', () => {
|
||||||
}, 10);
|
}, 10);
|
||||||
}, 10);
|
}, 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('vertical direction', () => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<div>
|
||||||
|
<el-carousel ref="carousel" :autoplay="false" direction="vertical" height="100px">
|
||||||
|
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
|
||||||
|
</el-carousel>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
});
|
||||||
|
const items = vm.$el.querySelectorAll('.el-carousel__item');
|
||||||
|
|
||||||
|
expect(vm.$refs.carousel.direction).to.be.equal('vertical');
|
||||||
|
expect(items[0].style.transform.indexOf('translateY') !== -1).to.be.true;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ export type CarouselIndicatorTrigger = 'hover' | 'click'
|
||||||
export type CarouselIndicatorPosition = 'outside' | 'none'
|
export type CarouselIndicatorPosition = 'outside' | 'none'
|
||||||
export type CarouselArrowVisibility = 'always' | 'hover' | 'never'
|
export type CarouselArrowVisibility = 'always' | 'hover' | 'never'
|
||||||
export type CarouselType = 'card'
|
export type CarouselType = 'card'
|
||||||
|
export type CarouselDirection = 'horizontal' | 'vertical'
|
||||||
|
|
||||||
/** Loop a series of images or texts in a limited space */
|
/** Loop a series of images or texts in a limited space */
|
||||||
export declare class ElCarousel extends ElementUIComponent {
|
export declare class ElCarousel extends ElementUIComponent {
|
||||||
|
@ -31,6 +32,9 @@ export declare class ElCarousel extends ElementUIComponent {
|
||||||
/** Type of the Carousel */
|
/** Type of the Carousel */
|
||||||
type: CarouselType
|
type: CarouselType
|
||||||
|
|
||||||
|
/** Display direction */
|
||||||
|
direction: CarouselDirection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manually switch slide by index
|
* Manually switch slide by index
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue