Commit e9989f2b8527ae389b943db2c88675c92d98a5b6

Authored by Rijn
1 parent 373dfb3c

added horizontal dots

src/components/carousel/carousel.vue
1 1 <template>
2 2 <div :class="classes">
3   - <div :class="[prefixCls + '-arrow', 'left']" @click="add(-1)">
4   - <div class='placeholder'></div>
5   - <Icon type="arrow-left-b"></Icon>
6   - </div>
  3 + <button :class="arrowClasses" class="left" @click="add(-1)">
  4 + <Icon type="chevron-left"></Icon>
  5 + </button>
7 6 <div :class="[prefixCls + '-list']">
8 7 <div :class="[prefixCls + '-track']" :style="trackStyles" v-el:slides>
9 8 <!-- opacity: 1; width: 4480px; transform: translate3d(-1120px, 0px, 0px); -->
10 9 <slot></slot>
11 10 </div>
12 11 </div>
13   - <div :class="[prefixCls + '-arrow', 'right']" @click="add(1)">
14   - <div class='placeholder'></div>
15   - <Icon type="arrow-right-b"></Icon>
16   - </div>
17   - <!-- dots -->
  12 + <button :class="arrowClasses" class="right" @click="add(1)">
  13 + <Icon type="chevron-right"></Icon>
  14 + </button>
  15 + <ul :class="dotsClasses">
  16 + <template v-for="n in slides.length">
  17 + <li :class="{ [`${prefixCls}-active`]: n === currentIndex }"
  18 + @click="dotsEvent('click', n)"
  19 + @mouseover="dotsEvent('hover', n)">
  20 + <button></button>
  21 + </li>
  22 + </template>
  23 + </ul>
18 24 </div>
19 25 </template>
20 26 <script>
... ... @@ -26,9 +32,9 @@
26 32 export default {
27 33 name: 'Carousel',
28 34 props: {
29   - arrows: {
30   - type: Boolean,
31   - default: false
  35 + arrow: {
  36 + type: String,
  37 + default: 'hover'
32 38 },
33 39 autoplay: {
34 40 type: Boolean,
... ... @@ -43,8 +49,12 @@
43 49 default: 'ease'
44 50 },
45 51 dots: {
46   - type: Boolean,
47   - default: true
  52 + type: String,
  53 + default: 'inside'
  54 + },
  55 + trigger: {
  56 + type: String,
  57 + default: 'click'
48 58 },
49 59 vertical: {
50 60 type: Boolean,
... ... @@ -66,7 +76,6 @@
66 76 timer: null
67 77 }
68 78 },
69   - // events: before-change(from, to), after-change(current, from)
70 79 computed: {
71 80 classes () {
72 81 return [
... ... @@ -82,6 +91,23 @@
82 91 transform: `translate3d(-${this.trackLeft}px, 0px, 0px)`,
83 92 transition: `transform 500ms ${this.easing}`
84 93 };
  94 + },
  95 + arrowClasses () {
  96 + return [
  97 + `${prefixCls}-arrow`,
  98 + `${prefixCls}-arrow-${this.arrow}`
  99 + ]
  100 + },
  101 + dotsClasses () {
  102 + return [
  103 + `${prefixCls}-dots`,
  104 + `${prefixCls}-arrow-${this.dots}`
  105 + ]
  106 + },
  107 + activeDot (n) {
  108 + return {
  109 + [`${prefixCls}-vertical`]: this.currentIndex === n
  110 + }
85 111 }
86 112 },
87 113 methods: {
... ... @@ -156,10 +182,14 @@
156 182 index += offset;
157 183 while (index < 0) index += this.slides.length;
158 184 index = index % this.slides.length;
  185 + this.$emit('on-change', this.currentIndex, index);
159 186 this.currentIndex = index;
160 187 },
161   - slide () {
162   - this.trackLeft = this.currentIndex * this.listWidth;
  188 + dotsEvent (event, n) {
  189 + if (event === this.trigger) {
  190 + this.$emit('on-change', this.currentIndex, n);
  191 + this.currentIndex = n;
  192 + }
163 193 },
164 194 setAutoplay () {
165 195 window.clearInterval(this.timer);
... ... @@ -182,7 +212,7 @@
182 212 },
183 213 currentIndex () {
184 214 this.$nextTick(() => {
185   - this.slide();
  215 + this.trackLeft = this.currentIndex * this.listWidth;
186 216 });
187 217 }
188 218 },
... ...
src/styles/components/carousel.less
... ... @@ -41,40 +41,123 @@
41 41 }
42 42  
43 43 &-arrow {
  44 +
  45 + border: none;
  46 + outline: none;
  47 +
  48 + padding: 0;
  49 + margin: 0;
  50 +
  51 + width: 36px;
  52 + height: 36px;
  53 + border-radius: 50%;
  54 +
  55 + cursor: pointer;
  56 +
  57 + display: none;
  58 +
44 59 position: absolute;
45   - top: 0;
46   - bottom: 0;
47   - height: 100%;
  60 + top: 50%;
  61 + z-index: 10;
  62 + transform: translateY(-50%);
  63 +
  64 + transition: .3s;
  65 + background-color: rgba(31, 45, 61, .11);
  66 + color: #fff;
  67 +
  68 + &:hover {
  69 + background-color: rgba(31, 45, 61, 0.5);
  70 + }
48 71  
49 72 text-align: center;
  73 + font-size: 1em;
  74 +
  75 + font-family: inherit;
  76 + line-height: inherit;
50 77  
51 78 & > * {
52   - display: inline-block;
53   - vertical-align: middle;
  79 + vertical-align: baseline;
54 80 }
55 81  
56   - .placeholder{
57   - overflow: hidden;
58   - width: 0;
59   - min-height: inherit;
60   - height: inherit;
  82 + &.left {
  83 + left: 16px;
61 84 }
62 85  
63   - z-index: 3;
  86 + &.right {
  87 + right: 16px;
  88 + }
64 89  
65   - &.left {
66   - left: 0;
  90 + &-always {
  91 + display: inherit;
67 92 }
68   - &.right {
69   - right: 0;
  93 +
  94 + &-hover {
  95 + display: inherit;
  96 +
  97 + opacity: 0;
70 98 }
  99 + }
71 100  
72   - width: 10%;
  101 + &:hover &-arrow-hover {
  102 + opacity: 1;
  103 + }
73 104  
74   - cursor: pointer;
  105 + &-dots {
  106 + @padding: 7px;
75 107  
76   - &:hover {
77   - background: fade(#000, 30%);
  108 + position: absolute;
  109 + bottom: 10px - @padding;
  110 +
  111 + list-style: none;
  112 + display: block;
  113 +
  114 + text-align: center;
  115 +
  116 + padding: 0;
  117 + width: 100%;
  118 + height: 3px + @padding * 2;
  119 +
  120 + li {
  121 + position: relative;
  122 + display: inline-block;
  123 +
  124 + vertical-align: top;
  125 + text-align: center;
  126 +
  127 + margin: 0 2px;
  128 + padding: @padding 0;
  129 +
  130 + cursor: pointer;
  131 +
  132 + button {
  133 + border: 0;
  134 + cursor: pointer;
  135 +
  136 + background: #8391a5;
  137 + opacity: 0.3;
  138 +
  139 + display: block;
  140 + width: 16px;
  141 + height: 3px;
  142 +
  143 + border-radius: 1px;
  144 + outline: none;
  145 +
  146 + font-size: 0;
  147 + color: transparent;
  148 +
  149 + -webkit-transition: all .5s;
  150 + transition: all .5s;
  151 + }
  152 +
  153 + &:hover > button {
  154 + opacity: 0.7;
  155 + }
  156 +
  157 + &.@{carousel-prefix-cls}-active > button {
  158 + opacity: 1;
  159 + width: 24px;
  160 + }
78 161 }
79 162 }
80 163 }
... ...
test/routers/carousel.vue
... ... @@ -21,13 +21,39 @@
21 21 </i-col>
22 22 <i-col span="4">
23 23 <i-button @click="push">Push</i-button>
24   - <i-button @click="remove = true">Remove</i-button>
  24 + <i-button @click="remove = true">Remove Front</i-button>
  25 + </i-col>
  26 + <i-col span="4">
  27 + <p>Dots</p>
  28 + <Button-group>
  29 + <i-button @click="dots = 'inside'">Inside</i-button>
  30 + <i-button @click="dots = 'outside'">Outside</i-button>
  31 + <i-button @click="dots = 'none'">None</i-button>
  32 + </Button-group>
  33 + </i-col>
  34 + <i-col span="4">
  35 + <p>Trigger</p>
  36 + <Button-group>
  37 + <i-button @click="trigger = 'click'">Click</i-button>
  38 + <i-button @click="trigger = 'hover'">Hover</i-button>
  39 + </Button-group>
  40 + </i-col>
  41 + <i-col span="4">
  42 + Arrow
  43 + <Button-group>
  44 + <i-button @click="arrow = 'hover'">Hover</i-button>
  45 + <i-button @click="arrow = 'always'">Always</i-button>
  46 + <i-button @click="arrow = 'never'">Never</i-button>
  47 + </Button-group>
25 48 </i-col>
26 49 </Row>
27 50 <Carousel style="width: 50%; border: solid 1px #000"
28 51 :current-index.sync="currentIndex"
29 52 :autoplay="autoplay"
30 53 :autoplay-speed="autoplaySpeed"
  54 + :dots="dots"
  55 + :trigger="trigger"
  56 + :arrow="arrow"
31 57 easing="linear">
32 58 <Carousel-item v-if="!remove">
33 59 <Alert type="warning" show-icon>
... ... @@ -54,7 +80,10 @@
54 80 autoplay: true,
55 81 autoplaySpeed: 2000,
56 82 remove: false,
57   - pushItem: []
  83 + pushItem: [],
  84 + arrow: 'hover',
  85 + trigger: 'click',
  86 + dots: 'inside'
58 87 }
59 88 },
60 89 methods: {
... ...