Blame view

src/components/carousel/carousel.vue 11.3 KB
6c9acb08   Rijn   initialize carousel
1
  <template>
41f83010   Rijn   update props and ...
2
      <div :class="classes">
932db623   Rijn   remove autoplay d...
3
          <button :class="arrowClasses" class="left" @click="arrowEvent(-1)">
e9989f2b   Rijn   added horizontal ...
4
5
              <Icon type="chevron-left"></Icon>
          </button>
65c64ce9   Rijn   carousel basic po...
6
          <div :class="[prefixCls + '-list']">
ccf544dc   houyl   Merge branch 'mas...
7
              <div :class="[prefixCls + '-track', showCopyTrack ? '' : 'higher']" :style="trackStyles" ref="originTrack">
65c64ce9   Rijn   carousel basic po...
8
9
                  <slot></slot>
              </div>
ccf544dc   houyl   Merge branch 'mas...
10
11
              <div :class="[prefixCls + '-track', showCopyTrack ? 'higher' : '']" :style="copyTrackStyles" ref="copyTrack" v-if="loop">
              </div>
65c64ce9   Rijn   carousel basic po...
12
          </div>
932db623   Rijn   remove autoplay d...
13
          <button :class="arrowClasses" class="right" @click="arrowEvent(1)">
e9989f2b   Rijn   added horizontal ...
14
15
16
17
              <Icon type="chevron-right"></Icon>
          </button>
          <ul :class="dotsClasses">
              <template v-for="n in slides.length">
bb71140e   梁灏   support Carousel
18
19
20
                  <li :class="[n - 1 === currentIndex ? prefixCls + '-active' : '']"
                      @click="dotsEvent('click', n - 1)"
                      @mouseover="dotsEvent('hover', n - 1)">
ccf544dc   houyl   Merge branch 'mas...
21
                      <button :class="[radiusDot ? 'radius' : '']"></button>
e9989f2b   Rijn   added horizontal ...
22
23
24
                  </li>
              </template>
          </ul>
6c9acb08   Rijn   initialize carousel
25
26
27
      </div>
  </template>
  <script>
41f83010   Rijn   update props and ...
28
      import Icon from '../icon/icon.vue';
53e38f9c   Rijn   added prop valida...
29
      import { getStyle, oneOf } from '../../utils/assist';
1dad8a57   梁灏   update Carousel
30
      import { on, off } from '../../utils/dom';
41f83010   Rijn   update props and ...
31
32
  
      const prefixCls = 'ivu-carousel';
6c9acb08   Rijn   initialize carousel
33
34
  
      export default {
41f83010   Rijn   update props and ...
35
          name: 'Carousel',
50f4ac70   Rijn   Merge branch 'mas...
36
          components: { Icon },
41f83010   Rijn   update props and ...
37
          props: {
e9989f2b   Rijn   added horizontal ...
38
39
              arrow: {
                  type: String,
53e38f9c   Rijn   added prop valida...
40
41
42
43
                  default: 'hover',
                  validator (value) {
                      return oneOf(value, ['hover', 'always', 'never']);
                  }
41f83010   Rijn   update props and ...
44
45
46
              },
              autoplay: {
                  type: Boolean,
5139233b   梁灏   update Carousel
47
                  default: false
41f83010   Rijn   update props and ...
48
49
50
51
52
              },
              autoplaySpeed: {
                  type: Number,
                  default: 2000
              },
ccf544dc   houyl   Merge branch 'mas...
53
54
55
56
              loop: {
                  type: Boolean,
                  default: false
              },
41f83010   Rijn   update props and ...
57
58
59
60
61
              easing: {
                  type: String,
                  default: 'ease'
              },
              dots: {
e9989f2b   Rijn   added horizontal ...
62
                  type: String,
53e38f9c   Rijn   added prop valida...
63
64
65
66
                  default: 'inside',
                  validator (value) {
                      return oneOf(value, ['inside', 'outside', 'none']);
                  }
e9989f2b   Rijn   added horizontal ...
67
              },
ccf544dc   houyl   Merge branch 'mas...
68
69
70
71
              radiusDot: {
                  type: Boolean,
                  default: false
              },
e9989f2b   Rijn   added horizontal ...
72
73
              trigger: {
                  type: String,
53e38f9c   Rijn   added prop valida...
74
75
76
77
                  default: 'click',
                  validator (value) {
                      return oneOf(value, ['click', 'hover']);
                  }
41f83010   Rijn   update props and ...
78
              },
bb71140e   梁灏   support Carousel
79
              value: {
3e6d6356   Rijn   implement basic t...
80
81
                  type: Number,
                  default: 0
9cd69375   Rijn   added height props
82
83
84
              },
              height: {
                  type: [String, Number],
53e38f9c   Rijn   added prop valida...
85
86
                  default: 'auto',
                  validator (value) {
0b1b650d   Rijn   fix #269.
87
                      return value === 'auto' || Object.prototype.toString.call(value) === '[object Number]';
53e38f9c   Rijn   added prop valida...
88
                  }
41f83010   Rijn   update props and ...
89
90
              }
          },
65c64ce9   Rijn   carousel basic po...
91
92
93
94
95
          data () {
              return {
                  prefixCls: prefixCls,
                  listWidth: 0,
                  trackWidth: 0,
9cd69375   Rijn   added height props
96
                  trackOffset: 0,
ccf544dc   houyl   Merge branch 'mas...
97
98
                  trackCopyOffset: 0,
                  showCopyTrack: false,
65c64ce9   Rijn   carousel basic po...
99
                  slides: [],
3e6d6356   Rijn   implement basic t...
100
                  slideInstances: [],
9cd69375   Rijn   added height props
101
                  timer: null,
bb71140e   梁灏   support Carousel
102
                  ready: false,
ccf544dc   houyl   Merge branch 'mas...
103
104
105
106
                  currentIndex: this.value,
                  trackIndex: this.value,
                  copyTrackIndex: this.value,
                  hideTrackPos: -1, // 默认左滑
50f4ac70   Rijn   Merge branch 'mas...
107
              };
65c64ce9   Rijn   carousel basic po...
108
          },
41f83010   Rijn   update props and ...
109
110
111
          computed: {
              classes () {
                  return [
9cd69375   Rijn   added height props
112
                      `${prefixCls}`
41f83010   Rijn   update props and ...
113
                  ];
65c64ce9   Rijn   carousel basic po...
114
              },
65c64ce9   Rijn   carousel basic po...
115
116
              trackStyles () {
                  return {
3e6d6356   Rijn   implement basic t...
117
                      width: `${this.trackWidth}px`,
ccf544dc   houyl   Merge branch 'mas...
118
                      transform: `translate3d(${-this.trackOffset}px, 0px, 0px)`,
3e6d6356   Rijn   implement basic t...
119
                      transition: `transform 500ms ${this.easing}`
65c64ce9   Rijn   carousel basic po...
120
                  };
e9989f2b   Rijn   added horizontal ...
121
              },
ccf544dc   houyl   Merge branch 'mas...
122
123
124
125
126
127
128
129
130
              copyTrackStyles () {
                  return {
                      width: `${this.trackWidth}px`,
                      transform: `translate3d(${-this.trackCopyOffset}px, 0px, 0px)`,
                      transition: `transform 500ms ${this.easing}`,
                      position: 'absolute',
                      top: 0
                  };
              },
e9989f2b   Rijn   added horizontal ...
131
132
133
134
              arrowClasses () {
                  return [
                      `${prefixCls}-arrow`,
                      `${prefixCls}-arrow-${this.arrow}`
50f4ac70   Rijn   Merge branch 'mas...
135
                  ];
e9989f2b   Rijn   added horizontal ...
136
137
138
139
              },
              dotsClasses () {
                  return [
                      `${prefixCls}-dots`,
8738f4d3   Rijn   added outside dots
140
                      `${prefixCls}-dots-${this.dots}`
50f4ac70   Rijn   Merge branch 'mas...
141
                  ];
65c64ce9   Rijn   carousel basic po...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
              }
          },
          methods: {
              // find option component
              findChild (cb) {
                  const find = function (child) {
                      const name = child.$options.componentName;
  
                      if (name) {
                          cb(child);
                      } else if (child.$children.length) {
                          child.$children.forEach((innerChild) => {
                              find(innerChild, cb);
                          });
                      }
                  };
  
9cd69375   Rijn   added height props
159
                  if (this.slideInstances.length || !this.$children) {
65c64ce9   Rijn   carousel basic po...
160
161
162
163
164
165
166
167
168
                      this.slideInstances.forEach((child) => {
                          find(child);
                      });
                  } else {
                      this.$children.forEach((child) => {
                          find(child);
                      });
                  }
              },
ccf544dc   houyl   Merge branch 'mas...
169
170
171
172
173
174
              // copy trackDom
              initCopyTrackDom () {
                  this.$nextTick(() => {
                      this.$refs.copyTrack.innerHTML = this.$refs.originTrack.innerHTML;
                  });
              },
bb71140e   梁灏   support Carousel
175
              updateSlides (init) {
65c64ce9   Rijn   carousel basic po...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
                  let slides = [];
                  let index = 1;
  
                  this.findChild((child) => {
                      slides.push({
                          $el: child.$el
                      });
                      child.index = index++;
  
                      if (init) {
                          this.slideInstances.push(child);
                      }
                  });
  
                  this.slides = slides;
8f4e2cf0   Rijn   update pos when s...
191
                  this.updatePos();
65c64ce9   Rijn   carousel basic po...
192
193
194
195
              },
              updatePos () {
                  this.findChild((child) => {
                      child.width = this.listWidth;
9cd69375   Rijn   added height props
196
                      child.height = typeof this.height === 'number' ? `${this.height}px` : this.height;
65c64ce9   Rijn   carousel basic po...
197
198
199
200
201
202
                  });
  
                  this.trackWidth = (this.slides.length || 0) * this.listWidth;
              },
              // use when slot changed
              slotChange () {
373dfb3c   Rijn   removed observer
203
204
205
206
207
208
                  this.$nextTick(() => {
                      this.slides = [];
                      this.slideInstances = [];
  
                      this.updateSlides(true, true);
                      this.updatePos();
62808b2b   Rijn   reset autoplay ti...
209
                      this.updateOffset();
373dfb3c   Rijn   removed observer
210
                  });
65c64ce9   Rijn   carousel basic po...
211
212
              },
              handleResize () {
9cd69375   Rijn   added height props
213
214
                  this.listWidth = parseInt(getStyle(this.$el, 'width'));
                  this.updatePos();
62808b2b   Rijn   reset autoplay ti...
215
                  this.updateOffset();
3e6d6356   Rijn   implement basic t...
216
              },
ccf544dc   houyl   Merge branch 'mas...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
              updateTrackPos (index) {
                  if (this.showCopyTrack) {
                      this.trackIndex = index;
                  } else {
                      this.copyTrackIndex = index;
                  }
              },
              updateTrackIndex (index) {
                  if (this.showCopyTrack) {
                      this.copyTrackIndex = index;
                  } else {
                      this.trackIndex = index;
                  }
              },
77d460e8   Rijn   added offset func...
231
              add (offset) {
ccf544dc   houyl   Merge branch 'mas...
232
233
234
235
236
237
238
239
240
241
242
243
244
245
                  // 获取单个轨道的图片数
                  let slidesLen = this.slides.length;
                  // 如果是无缝滚动,需要初始化双轨道位置
                  if (this.loop) {
                      if (offset > 0) {
                          // 初始化左滑轨道位置
                          this.hideTrackPos = -1;
                      } else {
                          // 初始化右滑轨道位置
                          this.hideTrackPos = slidesLen;
                      }
                      this.updateTrackPos(this.hideTrackPos);
                  }
                  // 获取当前展示图片的索引值
2073853e   梁灏   fixed #3038
246
247
                  const oldIndex = this.showCopyTrack ? this.copyTrackIndex : this.trackIndex;
                  let index = oldIndex + offset;
ccf544dc   houyl   Merge branch 'mas...
248
                  while (index < 0) index += slidesLen;
610fd3a5   houyl   [fix bug] carous...
249
                  if (((offset > 0 && index === slidesLen) || (offset < 0 && index === slidesLen - 1)) && this.loop) {
ccf544dc   houyl   Merge branch 'mas...
250
251
252
253
254
255
256
257
                      // 极限值(左滑:当前索引为总图片张数, 右滑:当前索引为总图片张数 - 1)切换轨道
                      this.showCopyTrack = !this.showCopyTrack;
                      this.trackIndex += offset;
                      this.copyTrackIndex += offset;
                  } else {
                      if (!this.loop) index = index % this.slides.length;
                      this.updateTrackIndex(index);
                  }
2073853e   梁灏   fixed #3038
258
259
260
                  this.currentIndex = index === this.slides.length ? 0 : index;
                  this.$emit('on-change', oldIndex, this.currentIndex);
                  this.$emit('input', this.currentIndex);
77d460e8   Rijn   added offset func...
261
              },
932db623   Rijn   remove autoplay d...
262
263
264
265
              arrowEvent (offset) {
                  this.setAutoplay();
                  this.add(offset);
              },
e9989f2b   Rijn   added horizontal ...
266
              dotsEvent (event, n) {
ccf544dc   houyl   Merge branch 'mas...
267
268
269
                  let curIndex = this.showCopyTrack ? this.copyTrackIndex : this.trackIndex;
                  if (event === this.trigger && curIndex !== n) {
                      this.updateTrackIndex(n);
bb71140e   梁灏   support Carousel
270
                      this.$emit('input', n);
62808b2b   Rijn   reset autoplay ti...
271
272
                      // Reset autoplay timer when trigger be activated
                      this.setAutoplay();
e9989f2b   Rijn   added horizontal ...
273
                  }
bfc11079   Rijn   updated autoplay ...
274
              },
3e6d6356   Rijn   implement basic t...
275
              setAutoplay () {
bfc11079   Rijn   updated autoplay ...
276
                  window.clearInterval(this.timer);
3e6d6356   Rijn   implement basic t...
277
278
                  if (this.autoplay) {
                      this.timer = window.setInterval(() => {
932db623   Rijn   remove autoplay d...
279
                          this.add(1);
3e6d6356   Rijn   implement basic t...
280
                      }, this.autoplaySpeed);
3e6d6356   Rijn   implement basic t...
281
                  }
9cd69375   Rijn   added height props
282
283
284
              },
              updateOffset () {
                  this.$nextTick(() => {
ccf544dc   houyl   Merge branch 'mas...
285
286
287
288
                      /* 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;
9cd69375   Rijn   added height props
289
                  });
41f83010   Rijn   update props and ...
290
              }
65c64ce9   Rijn   carousel basic po...
291
          },
3e6d6356   Rijn   implement basic t...
292
293
294
295
          watch: {
              autoplay () {
                  this.setAutoplay();
              },
bfc11079   Rijn   updated autoplay ...
296
297
298
              autoplaySpeed () {
                  this.setAutoplay();
              },
ccf544dc   houyl   Merge branch 'mas...
299
300
301
302
              trackIndex () {
                  this.updateOffset();
              },
              copyTrackIndex () {
9cd69375   Rijn   added height props
303
304
305
306
                  this.updateOffset();
              },
              height () {
                  this.updatePos();
bb71140e   梁灏   support Carousel
307
308
309
              },
              value (val) {
                  this.currentIndex = val;
b873063c   liumiaoxiang   Update carousel.vue
310
                  this.trackIndex = val;
3e6d6356   Rijn   implement basic t...
311
312
              }
          },
bb71140e   梁灏   support Carousel
313
314
          mounted () {
              this.updateSlides(true);
65c64ce9   Rijn   carousel basic po...
315
              this.handleResize();
bfc11079   Rijn   updated autoplay ...
316
              this.setAutoplay();
1dad8a57   梁灏   update Carousel
317
318
  //            window.addEventListener('resize', this.handleResize, false);
              on(window, 'resize', this.handleResize);
65c64ce9   Rijn   carousel basic po...
319
320
          },
          beforeDestroy () {
1dad8a57   梁灏   update Carousel
321
322
  //            window.removeEventListener('resize', this.handleResize, false);
              off(window, 'resize', this.handleResize);
41f83010   Rijn   update props and ...
323
          }
6c9acb08   Rijn   initialize carousel
324
325
      };
  </script>