add carousel

pull/1931/head
Leopoldthecoder 2016-12-22 16:10:55 +08:00
parent c20f5e9442
commit 9e958e603e
18 changed files with 966 additions and 32 deletions

View File

@ -54,5 +54,6 @@
"rate": "./packages/rate/index.js",
"steps": "./packages/steps/index.js",
"step": "./packages/step/index.js",
"carousel": "./packages/carousel/index.js"
"carousel": "./packages/carousel/index.js",
"carousel-item": "./packages/carousel-item/index.js"
}

View File

@ -1 +1,111 @@
## carousel
<script>
export default {
mounted() {
this.$nextTick(() => {
const demos = document.querySelectorAll('.source');
demos[0].style.padding = '0';
demos[0].className += ' small';
demos[3].className += ' medium';
});
}
}
</script>
## Carousel
Loop a series of images or texts in a limited space
### Basic usage
::: demo Combine `el-carousel` with `el-carousel-item`, and you'll get a carousel. Content of each slide is completely customizable, and you just need to place it inside `el-carousel-item` tag. By default the carousel switches when mouse hovers over an indicator. Set `trigger` to `click`, and the carousel switches only when an indicator is clicked.
```html
<template>
<div class="block">
<span class="demonstration">Switch when indicator is hovered (default)</span>
<el-carousel height="150px">
<el-carousel-item v-for="item in 4">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</div>
<div class="block">
<span class="demonstration">Switch when indicator is clicked</span>
<el-carousel trigger="click" height="150px">
<el-carousel-item v-for="item in 4">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</div>
</template>
```
:::
### Indicators
Indicators can be displayed outside the carousel
::: demo The `indicator-position` attribute determines where the indicators are located. By default they are inside the carousel, and setting `indicator-position` to `out` moves them outside.
```html
<template>
<el-carousel indicator-position="out">
<el-carousel-item v-for="item in 4">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</template>
```
:::
### Arrows
You can define when arrows are displayed
::: demo The `show-arrow` attribute determines when arrows are displayed. By default they appear when mouse hovers over the carousel. Setting `show-arrow` to `always` or `never` shows/hides the arrows permanently.
```html
<template>
<el-carousel :interval="5000" show-arrow="always">
<el-carousel-item v-for="item in 4">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</template>
```
:::
### Card mode
When a page is wide enough but has limited height, you can activate card mode for carousels
::: demo Setting `card` to `true` activates the card mode. Apart from the appearance, the biggest difference between card mode and common mode is that clicking the slides at both sides directly switches the carousel in card mode.
```html
<template>
<el-carousel :interval="4000" card height="200px">
<el-carousel-item v-for="item in 6">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</template>
```
:::
### Attributes
| Attribute | Description | Type | Accepted Values | Default |
|---------- |-------------- |---------- |-------------------------------- |-------- |
| height | height of the carousel | number | — | 300 |
| initial-index | index of the initially active slide (starting from 0) | number | — | 0 |
| trigger | how indicators are triggered | string | click | — |
| arrow-size | size of the arrows | number | — | 36 |
| interval | interval of the auto loop, in milliseconds. If less than or equal to 0, the carousel will not loop | number | — | 3000 |
| indicator-position | position of the indicators | string | out | — |
| show-indicator | whether indicators are shown | boolean | — | true |
| show-arrow | when arrows are shown | string | always/never | — |
| card | whether card mode is activated | boolean | — | false |
### Events
| Event Name | Description | Parameters |
|---------|---------|---------|
| index-change | triggers when the active slide switches | index of the new active slide, index of the old active slide |
### Methods
| Method | Description | Parameters |
|---------- |-------------- | - |
| setActiveIndex | manually switch slide | index of the slide to be switched to, starting from 0 |

View File

@ -809,10 +809,10 @@ Form component allows you to verify your data, helping you find and correct erro
### Form Methods
| Method | Description |
| ---- | ---- |
| validate(cb) | the method to validate the whole form |
| validateField(prop, cb) | the method to validate a certain form item |
| Method | Description | Parameters
| ---- | ---- | ----
| validate | the method to validate the whole form | Function(callback: Function(boolean))
| validateField | the method to validate a certain form item | Function(prop: string, callback: Function(errorMessage: string))
| resetFields | reset all the fields and remove validation result |
### Form-Item Attributes

View File

@ -1381,7 +1381,7 @@ Customize table column so it can be integrated with other components.
| current-change | triggers when current row changes | currentRow, oldCurrentRow |
### Table Methods
| Method | Description | Parameter |
| Method | Description | Parameters |
|------|--------|-------|
| clearSelection | clear selection, might be useful when `reserve-selection` is on | selection |
| toggleRowSelection | toggle if a certain row is selected. With the second parameter, you can directly set if this row is selected | row, selected |

View File

@ -1 +1,161 @@
## 走马灯
<script>
export default {
mounted() {
this.$nextTick(() => {
const demos = document.querySelectorAll('.source');
demos[0].style.padding = '0';
demos[0].className += ' small';
demos[3].className += ' medium';
});
}
}
</script>
<style>
.demo-carousel .block {
padding: 30px;
text-align: center;
border-right: solid 1px #EFF2F6;
float: left;
width: 50%;
box-sizing: border-box;
&:last-child {
border-right: none;
}
}
.demo-carousel .demonstration {
display: block;
color: #8492a6;
font-size: 14px;
margin-bottom: 20px;
}
.demo-carousel .el-carousel__container {
text-align: center;
}
.demo-carousel .el-carousel__item {
h3 {
color: #475669;
font-size: 18px;
opacity: 0.75;
line-height: 300px;
margin: 0;
}
&:nth-child(2n) {
background-color: #99a9bf;
}
&:nth-child(2n+1) {
background-color: #d3dce6;
}
}
.demo-carousel .small h3 {
font-size: 14px;
line-height: 150px;
}
.demo-carousel .medium h3 {
font-size: 14px;
line-height: 200px;
}
</style>
## Carousel 走马灯
在有限空间内,循环播放同一类型的图片、文字等内容
### 基础用法
适用广泛的基础用法
::: demo 结合使用`el-carousel`和`el-carousel-item`标签就得到了一个走马灯。幻灯片的内容是任意的,需要放在`el-carousel-item`标签中。默认情况下,在鼠标 hover 底部的切换条时就会触发切换。通过设置`trigger`属性为`click`,可以达到点击触发的效果。
```html
<template>
<div class="block">
<span class="demonstration">默认 Hover 切换条触发</span>
<el-carousel height="150px">
<el-carousel-item v-for="item in 4">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</div>
<div class="block">
<span class="demonstration">Click 切换条触发</span>
<el-carousel trigger="click" height="150px">
<el-carousel-item v-for="item in 4">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</div>
</template>
```
:::
### 切换条
可以将切换条的显示位置设置在容器外部
::: demo `indicator-position`属性定义了切换条的位置。默认情况下,它会显示在走马灯内部,设置为`out`则会显示在外部。
```html
<template>
<el-carousel indicator-position="out">
<el-carousel-item v-for="item in 4">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</template>
```
:::
### 切换箭头
可以设置切换箭头的显示时机
::: demo `show-arrow`属性定义了切换箭头的显示时机。默认情况下,切换箭头只有在鼠标 hover 到走马灯上时才会显示;若将`show-arrow`设置为`always`,则会一直显示;设置为`never`,则会一直隐藏。
```html
<template>
<el-carousel :interval="5000" show-arrow="always">
<el-carousel-item v-for="item in 4">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</template>
```
:::
### 卡片化
当页面宽度方向空间空余,但高度方向空间匮乏时,可使用卡片风格
::: demo 设置`card`属性即可启用卡片模式。从交互上来说,卡片模式和一般模式的最大区别在于,可以通过直接点击两侧的幻灯片进行切换。
```html
<template>
<el-carousel :interval="4000" card height="200px">
<el-carousel-item v-for="item in 6">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</template>
```
:::
### Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- |
| height | 走马灯的高度 | number | — | 300 |
| initial-index | 初始状态激活的幻灯片的索引,从 0 开始 | number | — | 0 |
| trigger | 切换条的触发方式 | string | click | — |
| arrow-size | 切换箭头的大小 | number | — | 36 |
| interval | 自动切换的时间间隔,单位为毫秒。若小于等于 0则不会自动切换 | number | — | 3000 |
| indicator-position | 切换条的位置 | string | out | — |
| show-indicator | 是否显示切换条 | boolean | — | true |
| show-arrow | 切换箭头的显示时机 | string | always/never | — |
| card | 是否启用卡片模式 | boolean | — | false |
### Events
| 事件名称 | 说明 | 回调参数 |
|---------|---------|---------|
| index-change | 幻灯片切换时触发 | 目前激活的幻灯片的索引,原幻灯片的索引 |
### Methods
| 方法名 | 说明 | 参数 |
|---------- |-------------- | - |
| setActiveIndex | 手动切换幻灯片 | 需要切换的幻灯片的索引,从 0 开始 |

View File

@ -0,0 +1,8 @@
import ElCarouselItem from '../carousel/src/item';
/* istanbul ignore next */
ElCarouselItem.install = function(Vue) {
Vue.component(ElCarouselItem.name, ElCarouselItem);
};
export default ElCarouselItem;

View File

@ -0,0 +1,10 @@
import ElCarousel from './src/main';
import ElCarouselItem from './src/item';
/* istanbul ignore next */
export default function(Vue) {
Vue.component(ElCarousel.name, ElCarousel);
Vue.component(ElCarouselItem.name, ElCarouselItem);
};
export { ElCarousel, ElCarouselItem };

View File

@ -4,7 +4,7 @@ var config = require('../../build/config');
cooking.set({
entry: {
index: path.join(__dirname, 'index.js')
index: path.join(__dirname, '_index.js')
},
dist: path.join(__dirname, 'lib'),
template: false,

View File

@ -2,14 +2,16 @@
"name": "element-carousel",
"version": "0.0.0",
"description": "A carousel component for Vue.js.",
"main": "lib/index.js",
"keywords": [
"element",
"vue",
"component"
],
"main": "./lib/index.js",
"repository": "https://github.com/ElemeFE/element/tree/master/packages/carousel",
"author": "elemefe",
"license": "MIT",
"dependencies": {}
"dependencies": {
"throttle-debounce": "^1.0.1"
}
}

View File

@ -0,0 +1,96 @@
<template>
<div
v-show="ready"
class="el-carousel__item"
:class="{
'is-active': active,
'is-card': $parent.card,
'is-in-stage': inStage
}"
@click="handleItemClick"
:style="{ transform: `translateX(${ translate }px) scale(${ scale })` }">
<div
v-if="$parent.card"
v-show="!active"
class="el-carousel__mask">
</div>
<slot></slot>
</div>
</template>
<script>
const CARD_SCALE = 0.83;
export default {
name: 'ElCarouselItem',
data() {
return {
translate: 0,
scale: 1,
active: false,
ready: false,
inStage: false
};
},
methods: {
processIndex(index, activeIndex, length) {
if (activeIndex === 0 && index === length - 1) {
return -1;
} else if (activeIndex === length - 1 && index === 0) {
return length;
} else if (index < activeIndex - 1 && activeIndex - index >= length / 2) {
return length + 1;
} else if (index > activeIndex + 1 && index - activeIndex >= length / 2) {
return -2;
}
return index;
},
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;
}
},
translateItem(index, activeIndex) {
const parentWidth = this.$parent.$el.offsetWidth;
const length = this.$parent.items.length;
if (this.$parent.card) {
if (index !== activeIndex && length > 2) {
index = this.processIndex(index, activeIndex, length);
}
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;
},
handleItemClick() {
const parent = this.$parent;
if (parent && parent.card) {
const index = parent.items.indexOf(this);
parent.setActiveIndex(index);
}
}
},
created() {
this.$parent && this.$parent.handleItemChange();
},
destroyed() {
this.$parent && this.$parent.handleItemChange();
}
};
</script>

View File

@ -1,9 +1,198 @@
<template>
<div class="el-carousel"></div>
<div
class="el-carousel"
:class="{ 'is-card': card }"
@mouseenter.stop="handleMouseEnter"
@mouseleave.stop="handleMouseLeave">
<div
class="el-carousel__container"
:style="{ height: height }">
<transition name="carousel-arrow-left">
<button
v-if="showArrow !== 'never'"
v-show="showArrow === 'always' || hover"
:style="{
height: `${ arrowSize }px`,
width: `${ arrowSize }px`
}"
@click="throttledArrowClick(activeIndex - 1)"
class="el-carousel__arrow is-left">
<i class="el-icon-arrow-left"></i>
</button>
</transition>
<transition name="carousel-arrow-right">
<button
v-if="showArrow !== 'never'"
v-show="showArrow === 'always' || hover"
:style="{
height: `${ arrowSize }px`,
width: `${ arrowSize }px`
}"
@click="throttledArrowClick(activeIndex + 1)"
class="el-carousel__arrow is-right">
<i class="el-icon-arrow-right"></i>
</button>
</transition>
<slot></slot>
</div>
<ul
class="el-carousel__indicators"
v-if="showIndicator"
:class="{ 'is-out': indicatorPosition === 'out' || 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"></button>
</li>
</ul>
</div>
</template>
<script>
import throttle from 'throttle-debounce/throttle';
export default {
name: 'ElCarousel'
name: 'ElCarousel',
props: {
initialIndex: {
type: Number,
default: 0
},
height: String,
trigger: {
type: String,
default: 'hover'
},
arrowSize: {
type: Number,
default: 36
},
interval: {
type: Number,
default: 3000
},
indicatorPosition: String,
showIndicator: {
type: Boolean,
default: true
},
showArrow: String,
card: Boolean
},
data() {
return {
items: [],
activeIndex: -1,
containerWidth: 0,
reInitTimer: null,
timer: null,
hover: false
};
},
watch: {
activeIndex(val, oldVal) {
this.resetItemPosition();
this.$emit('index-change', val, oldVal);
}
},
methods: {
handleMouseEnter() {
this.hover = true;
this.pauseTimer();
},
handleMouseLeave() {
this.hover = false;
this.startTimer();
},
handleItemChange() {
clearTimeout(this.reInitTimer);
this.reInitTimer = setTimeout(() => {
this.setItems();
}, 100);
},
setItems() {
this.items = this.$children.filter(child => child.$options.name === 'ElCarouselItem');
},
resetItemPosition() {
this.items.forEach((item, index) => {
item.translateItem(index, this.activeIndex);
});
},
autoPlay() {
if (this.activeIndex < this.items.length - 1) {
this.activeIndex++;
} else {
this.activeIndex = 0;
}
},
pauseTimer() {
clearInterval(this.timer);
},
startTimer() {
if (this.interval <= 0) return;
this.timer = setInterval(this.autoPlay, this.interval);
},
setActiveIndex(index) {
index = Number(index);
if (isNaN(index)) return;
let length = this.items.length;
if (index < 0) {
this.activeIndex = length - 1;
} else if (index >= length) {
this.activeIndex = 0;
} else {
this.activeIndex = index;
}
},
handleIndicatorClick(index) {
this.activeIndex = index;
},
handleIndicatorHover(index) {
if (this.trigger === 'hover' && index !== this.activeIndex) {
this.activeIndex = index;
}
}
},
created() {
this.throttledArrowClick = throttle(300, true, index => {
this.setActiveIndex(index);
});
this.throttledIndicatorHover = throttle(300, index => {
this.handleIndicatorHover(index);
});
window.addEventListener('resize', this.resetItemPosition);
},
mounted() {
this.setItems();
this.$nextTick(() => {
if (this.initialIndex < this.items.length && this.initialIndex >= 0) {
this.activeIndex = this.initialIndex;
}
this.startTimer();
});
},
beforeDestroy() {
window.removeEventListener('resize', this.resetItemPosition);
}
};
</script>

View File

@ -0,0 +1,44 @@
@charset "UTF-8";
@import "./common/var.css";
@component-namespace el {
@b carousel {
@e item {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: inline-block;
transition: .4s ease-in-out;
overflow: hidden;
@when card {
width: 50%;
z-index: calc(var(--index-normal) - 1);
&.is-in-stage {
cursor: pointer;
z-index: var(--index-normal);
&:hover .el-carousel__mask {
opacity: 0.12;
}
}
&.is-active {
z-index: calc(var(--index-normal) + 1);
}
}
}
@e mask {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: var(--color-white);
opacity: 0.24;
transition: .2s;
}
}
}

View File

@ -0,0 +1,115 @@
@charset "UTF-8";
@import "./common/var.css";
@component-namespace el {
@b carousel {
overflow-x: hidden;
position: relative;
@e container {
position: relative;
height: 300px;
}
@e arrow {
border: none;
outline: none;
padding: 0;
margin: 0;
cursor: pointer;
transition: .3s;
border-radius: 50%;
background-color: var(--carousel-arrow-background);
color: var(--color-white);
position: absolute;
top: 50%;
z-index: 10;
transform: translateY(-50%);
text-align: center;
font-size: var(--carousel-arrow-font-size);
@when left {
left: 16px;
}
@when right {
right: 16px;
}
&:hover {
background-color: var(--carousel-arrow-hover-background);
}
& i {
cursor: pointer;
}
}
@e indicators {
position: absolute;
list-style: none;
bottom: 0;
left: 50%;
transform: translateX(-50%);
margin: 0;
padding: 0;
@when out {
bottom: calc(var(--carousel-indicator-height) + var(--carousel-indicator-padding-vertical) * 2);
text-align: center;
position: static;
transform: none;
.el-carousel__indicator:hover button {
opacity: 0.64;
}
button {
background-color: var(--carousel-indicator-out-color);
opacity: 0.24;
}
}
}
@e indicator {
display: inline-block;
background-color: transparent;
padding: var(--carousel-indicator-padding-vertical) var(--carousel-indicator-padding-horizontal);
cursor: pointer;
&:hover button {
opacity: 0.72;
}
@when active {
button {
opacity: 1;
}
}
}
@e button {
display: block;
opacity: 0.48;
size: var(--carousel-indicator-width) var(--carousel-indicator-height);
background-color: var(--color-white);
border: none;
outline: none;
padding: 0;
margin: 0;
cursor: pointer;
transition: .3s;
}
}
.carousel-arrow-left-enter,
.carousel-arrow-left-leave-active {
transform: translateY(-50%) translateX(-10px);
opacity: 0;
}
.carousel-arrow-right-enter,
.carousel-arrow-right-leave-active {
transform: translateY(-50%) translateX(10px);
opacity: 0;
}
}

View File

@ -544,4 +544,15 @@
--------------------------*/
--loading-spinner-size: 42px;
--loading-fullscreen-spinner-size: 50px;
/* Carousel
--------------------------*/
--carousel-arrow-font-size: 12px;
--carousel-arrow-background: rgba(31, 45, 61, 0.11);
--carousel-arrow-hover-background: rgba(31, 45, 61, 0.23);
--carousel-indicator-width: 30px;
--carousel-indicator-height: 2px;
--carousel-indicator-padding-horizontal: 4px;
--carousel-indicator-padding-vertical: 12px;
--carousel-indicator-out-color: var(--border-color-hover);
}

View File

@ -40,3 +40,5 @@
@import "./rate.css";
@import "./steps.css";
@import "./step.css";
@import "./carousel.css";
@import "./carousel-item.css";

View File

@ -55,6 +55,8 @@ import Card from '../packages/card';
import Rate from '../packages/rate';
import Steps from '../packages/steps';
import Step from '../packages/step';
import Carousel from '../packages/carousel';
import CarouselItem from '../packages/carousel-item';
import locale from 'element-ui/src/locale';
const install = function(Vue, opts = {}) {
@ -113,6 +115,8 @@ const install = function(Vue, opts = {}) {
Vue.component(Rate.name, Rate);
Vue.component(Steps.name, Steps);
Vue.component(Step.name, Step);
Vue.component(Carousel.name, Carousel);
Vue.component(CarouselItem.name, CarouselItem);
Vue.use(Loading.directive);
@ -188,5 +192,7 @@ module.exports = {
Card,
Rate,
Steps,
Step
Step,
Carousel,
CarouselItem
};

View File

@ -1,5 +1,4 @@
import { createTest, destroyVM } from '../util';
import Carousel from 'packages/carousel';
import { createVue, destroyVM } from '../util';
describe('Carousel', () => {
let vm;
@ -8,8 +7,189 @@ describe('Carousel', () => {
});
it('create', () => {
vm = createTest(Carousel, true);
expect(vm.$el).to.exist;
vm = createVue({
template: `
<div>
<el-carousel>
<el-carousel-item v-for="item in 3"></el-carousel-item>
</el-carousel>
</div>
`
});
expect(vm.$el.querySelectorAll('.el-carousel__item').length).to.equal(3);
});
it('auto play', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="50">
<el-carousel-item v-for="item in 3"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
const items = vm.$el.querySelectorAll('.el-carousel__item');
expect(items[0].classList.contains('is-active')).to.true;
setTimeout(() => {
expect(items[1].classList.contains('is-active')).to.true;
done();
}, 60);
}, 10);
});
it('initial index', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="0" :initial-index="1">
<el-carousel-item v-for="item in 3"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-carousel__item')[1].classList.contains('is-active')).to.true;
done();
}, 10);
});
it('reset timer', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="20">
<el-carousel-item v-for="item in 3"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
const carousel = vm.$children[0];
const items = vm.$el.querySelectorAll('.el-carousel__item');
carousel.handleMouseEnter();
setTimeout(() => {
expect(items[0].classList.contains('is-active')).to.true;
carousel.handleMouseLeave();
setTimeout(() => {
expect(items[1].classList.contains('is-active')).to.true;
done();
}, 30);
}, 20);
}, 10);
});
it('index change', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="50" @index-change="handleIndexChange">
<el-carousel-item v-for="item in 3"></el-carousel-item>
</el-carousel>
</div>
`,
data() {
return {
val: -1,
oldVal: -1
};
},
methods: {
handleIndexChange(val, oldVal) {
this.val = val;
this.oldVal = oldVal;
}
}
});
setTimeout(() => {
expect(vm.val).to.equal(1);
expect(vm.oldVal).to.equal(0);
done();
}, 100);
});
describe('manual control', () => {
it('hover', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="0">
<el-carousel-item v-for="item in 3"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
vm.$children[0].handleIndicatorHover(1);
setTimeout(() => {
expect(vm.$el.querySelectorAll('.el-carousel__item')[1].classList.contains('is-active')).to.true;
done();
}, 10);
}, 10);
});
it('click', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="0" trigger="click">
<el-carousel-item v-for="item in 3"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
const items = vm.$el.querySelectorAll('.el-carousel__item');
vm.$el.querySelectorAll('.el-carousel__indicator')[2].click();
setTimeout(() => {
expect(items[2].classList.contains('is-active')).to.true;
vm.$el.querySelector('.el-carousel__arrow.is-right').click();
setTimeout(() => {
expect(items[0].classList.contains('is-active')).to.true;
done();
}, 10);
}, 10);
}, 10);
});
});
it('card', done => {
vm = createVue({
template: `
<div>
<el-carousel :interval="0" card>
<el-carousel-item v-for="item in 7"></el-carousel-item>
</el-carousel>
</div>
`
});
setTimeout(() => {
const items = vm.$el.querySelectorAll('.el-carousel__item');
expect(items[0].classList.contains('is-active')).to.true;
expect(items[1].classList.contains('is-in-stage')).to.true;
expect(items[6].classList.contains('is-in-stage')).to.true;
items[1].click();
setTimeout(() => {
expect(items[1].classList.contains('is-active')).to.true;
vm.$el.querySelector('.el-carousel__arrow.is-left').click();
setTimeout(() => {
expect(items[0].classList.contains('is-active')).to.true;
items[6].click();
setTimeout(() => {
expect(items[6].classList.contains('is-active')).to.true;
done();
}, 10);
}, 10);
}, 10);
}, 10);
});
});

View File

@ -1317,11 +1317,12 @@ cooking-lint@^0.1.3:
eslint-plugin-react "*"
eslint-plugin-vue "*"
cooking-vue2@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/cooking-vue2/-/cooking-vue2-0.1.4.tgz#4344650f1252daace5955e60cd48a07adf876750"
cooking-vue2@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/cooking-vue2/-/cooking-vue2-0.3.0.tgz#a38062164d80df49a788b1669dcb45eddab91238"
dependencies:
vue-loader "^9.4.2"
vue-loader ">=9.4.2"
vue-template-compiler "*"
cooking@^1.2.0:
version "1.2.7"
@ -6835,9 +6836,9 @@ vue-hot-reload-api@^2.0.1:
version "2.0.6"
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.0.6.tgz#817d4bfb30f55428aa1012d029499e07f3147d21"
vue-loader@^9.4.2, vue-loader@^9.9.0:
version "9.9.5"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-9.9.5.tgz#0893e3093e90c8fbe852053b2b0f4854a3bf4651"
vue-loader@^10.0.2, vue-loader@>=9.4.2:
version "10.0.2"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-10.0.2.tgz#6fe7bcefb32c5439bd0338464aa22673ad62299c"
dependencies:
consolidate "^0.14.0"
hash-sum "^1.0.2"
@ -6850,7 +6851,6 @@ vue-loader@^9.4.2, vue-loader@^9.9.0:
source-map "^0.5.6"
vue-hot-reload-api "^2.0.1"
vue-style-loader "^1.0.0"
vue-template-compiler "^2.0.5"
vue-template-es2015-compiler "^1.2.2"
vue-markdown-loader@^0.5.1:
@ -6879,9 +6879,9 @@ vue-style-loader@^1.0.0:
dependencies:
loader-utils "^0.2.7"
vue-template-compiler@^2.0.5, vue-template-compiler@2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.0.5.tgz#6a8c454e7d4ed03cc295ae9733a432e31df25ea3"
vue-template-compiler@*, vue-template-compiler@2.1.6:
version "2.1.6"
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.1.6.tgz#f96f968652fc1e861bb0052f61993ba1fdc18ad3"
dependencies:
de-indent "^1.0.2"
he "^1.1.0"
@ -6890,9 +6890,9 @@ vue-template-es2015-compiler@^1.2.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.4.0.tgz#7b88853ca4bf8d84ae54ab9e56771de271e60198"
vue@2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.0.5.tgz#b99dc7180a802d1148a508db3d84b52c09b5ca8e"
vue@2.1.6:
version "2.1.6"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.1.6.tgz#2fc0024c07479ac6bc7d34a2cd5ef9ca5e90b143"
watchpack@^0.2.1:
version "0.2.9"