Blame view

src/components/modal/modal.vue 13.8 KB
be966e9f   梁灏   add Modal component
1
  <template>
548eac43   梁灏   fixed #1387 and u...
2
      <div v-transfer-dom :data-transfer="transfer">
672a2805   梁灏   fixed #505
3
          <transition :name="transitionNames[1]">
16c2b8d2   梁灏   fixes #4439
4
              <div :class="maskClasses" :style="wrapStyles" v-show="visible" v-if="showMask" @click="handleMask"></div>
6259471f   梁灏   support Modal
5
          </transition>
707a3d82   梁灏   update Modal for ...
6
          <div :class="wrapClasses" :style="wrapStyles" @click="handleWrapClick">
f3454b37   marvinwilliam   add modal hidden ...
7
              <transition :name="transitionNames[0]" @after-leave="animationFinish">
bb060b98   梁灏   fix #5800, close ...
8
                  <div :class="classes" :style="mainStyles" v-show="visible" @mousedown="handleMousedown">
707a3d82   梁灏   update Modal for ...
9
                      <div :class="contentClasses" ref="content" :style="contentStyles" @click="handleClickModal">
6259471f   梁灏   support Modal
10
11
                          <a :class="[prefixCls + '-close']" v-if="closable" @click="close">
                              <slot name="close">
06a4433d   梁灏   update Modal Icons
12
                                  <Icon type="ios-close"></Icon>
6259471f   梁灏   support Modal
13
14
                              </slot>
                          </a>
d4b59a9a   梁灏   Modal add dragabl...
15
16
17
18
                          <div :class="[prefixCls + '-header']"
                               @mousedown="handleMoveStart"
                               v-if="showHead"
                          ><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div>
6259471f   梁灏   support Modal
19
20
21
                          <div :class="[prefixCls + '-body']"><slot></slot></div>
                          <div :class="[prefixCls + '-footer']" v-if="!footerHide">
                              <slot name="footer">
e5337c81   梁灏   fixed some compon...
22
23
                                  <i-button type="text" size="large" @click.native="cancel">{{ localeCancelText }}</i-button>
                                  <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
6259471f   梁灏   support Modal
24
25
26
                              </slot>
                          </div>
                      </div>
be966e9f   梁灏   add Modal component
27
                  </div>
6259471f   梁灏   support Modal
28
              </transition>
be966e9f   梁灏   add Modal component
29
          </div>
713bd3d7   梁灏   fixed #583
30
      </div>
be966e9f   梁灏   add Modal component
31
32
33
  </template>
  <script>
      import Icon from '../icon';
4b7138b9   梁灏   fixed some bugs
34
      import iButton from '../button/button.vue';
713bd3d7   梁灏   fixed #583
35
      import TransferDom from '../../directives/transfer-dom';
e5337c81   梁灏   fixed some compon...
36
      import Locale from '../../mixins/locale';
67c9b1c8   梁灏   fixed #591
37
      import Emitter from '../../mixins/emitter';
297648f1   梁灏   fixed #1063
38
      import ScrollbarMixins from './mixins-scrollbar';
be966e9f   梁灏   add Modal component
39
  
d4b59a9a   梁灏   Modal add dragabl...
40
      import { on, off } from '../../utils/dom';
707a3d82   梁灏   update Modal for ...
41
42
      import { findComponentsDownward } from '../../utils/assist';
  
7bafe9d9   梁灏   fixes #4453 #4480...
43
      import { transferIndex as modalIndex, transferIncrease as modalIncrease } from '../../utils/transfer-queue';
d4b59a9a   梁灏   Modal add dragabl...
44
  
be966e9f   梁灏   add Modal component
45
46
47
      const prefixCls = 'ivu-modal';
  
      export default {
e5337c81   梁灏   fixed some compon...
48
          name: 'Modal',
297648f1   梁灏   fixed #1063
49
          mixins: [ Locale, Emitter, ScrollbarMixins ],
4b7138b9   梁灏   fixed some bugs
50
          components: { Icon, iButton },
713bd3d7   梁灏   fixed #583
51
          directives: { TransferDom },
be966e9f   梁灏   add Modal component
52
          props: {
6259471f   梁灏   support Modal
53
              value: {
be966e9f   梁灏   add Modal component
54
55
56
57
58
59
60
61
62
                  type: Boolean,
                  default: false
              },
              closable: {
                  type: Boolean,
                  default: true
              },
              maskClosable: {
                  type: Boolean,
67d3aba1   梁灏   Modal add global ...
63
64
65
                  default () {
                      return !this.$IVIEW || this.$IVIEW.modal.maskClosable === '' ? true : this.$IVIEW.modal.maskClosable;
                  }
be966e9f   梁灏   add Modal component
66
67
68
69
70
71
72
73
74
              },
              title: {
                  type: String
              },
              width: {
                  type: [Number, String],
                  default: 520
              },
              okText: {
e5337c81   梁灏   fixed some compon...
75
                  type: String
be966e9f   梁灏   add Modal component
76
77
              },
              cancelText: {
e5337c81   梁灏   fixed some compon...
78
                  type: String
be966e9f   梁灏   add Modal component
79
80
81
82
83
              },
              loading: {
                  type: Boolean,
                  default: false
              },
6259471f   梁灏   support Modal
84
              styles: {
be966e9f   梁灏   add Modal component
85
86
87
88
89
90
91
92
93
                  type: Object
              },
              className: {
                  type: String
              },
              // for instance
              footerHide: {
                  type: Boolean,
                  default: false
f9a2e611   Rijn   added scrolling p...
94
              },
5d0b89ce   Rijn   change scrolling ...
95
              scrollable: {
f9a2e611   Rijn   added scrolling p...
96
97
                  type: Boolean,
                  default: false
672a2805   梁灏   fixed #505
98
99
100
101
102
103
              },
              transitionNames: {
                  type: Array,
                  default () {
                      return ['ease', 'fade'];
                  }
548eac43   梁灏   fixed #1387 and u...
104
105
106
              },
              transfer: {
                  type: Boolean,
e44ba4d4   梁灏   Modal support glo...
107
                  default () {
fe5ffd7f   梁灏   fixed #4196 #4165
108
                      return !this.$IVIEW || this.$IVIEW.transfer === '' ? true : this.$IVIEW.transfer;
e44ba4d4   梁灏   Modal support glo...
109
                  }
d42d4def   梁灏   Modal add fullscr...
110
111
112
113
              },
              fullscreen: {
                  type: Boolean,
                  default: false
1c7289e9   梁灏   Modal add mask & ...
114
115
116
117
118
              },
              mask: {
                  type: Boolean,
                  default: true
              },
1210cfe5   梁灏   update Modal prop...
119
              draggable: {
1c7289e9   梁灏   Modal add mask & ...
120
121
                  type: Boolean,
                  default: false
707a3d82   梁灏   update Modal for ...
122
123
124
125
126
              },
              zIndex: {
                  type: Number,
                  default: 1000
              },
be966e9f   梁灏   add Modal component
127
128
129
130
131
132
          },
          data () {
              return {
                  prefixCls: prefixCls,
                  wrapShow: false,
                  showHead: true,
6259471f   梁灏   support Modal
133
                  buttonLoading: false,
d4b59a9a   梁灏   Modal add dragabl...
134
135
136
137
138
139
140
                  visible: this.value,
                  dragData: {
                      x: null,
                      y: null,
                      dragX: null,
                      dragY: null,
                      dragging: false
707a3d82   梁灏   update Modal for ...
141
142
                  },
                  modalIndex: this.handleGetModalIndex(),  // for Esc close the top modal
bb060b98   梁灏   fix #5800, close ...
143
                  isMouseTriggerIn: false, // #5800
b0893113   jingsam   :art: add eslint
144
              };
be966e9f   梁灏   add Modal component
145
146
147
148
149
150
151
          },
          computed: {
              wrapClasses () {
                  return [
                      `${prefixCls}-wrap`,
                      {
                          [`${prefixCls}-hidden`]: !this.wrapShow,
1c7289e9   梁灏   Modal add mask & ...
152
153
                          [`${this.className}`]: !!this.className,
                          [`${prefixCls}-no-mask`]: !this.showMask
be966e9f   梁灏   add Modal component
154
                      }
b0893113   jingsam   :art: add eslint
155
                  ];
be966e9f   梁灏   add Modal component
156
              },
707a3d82   梁灏   update Modal for ...
157
158
159
160
161
              wrapStyles () {
                  return {
                      zIndex: this.modalIndex + this.zIndex
                  };
              },
be966e9f   梁灏   add Modal component
162
163
164
165
              maskClasses () {
                  return `${prefixCls}-mask`;
              },
              classes () {
d42d4def   梁灏   Modal add fullscr...
166
167
168
169
170
171
                  return [
                      `${prefixCls}`,
                      {
                          [`${prefixCls}-fullscreen`]: this.fullscreen,
                          [`${prefixCls}-fullscreen-no-header`]: this.fullscreen && !this.showHead,
                          [`${prefixCls}-fullscreen-no-footer`]: this.fullscreen && this.footerHide
1c7289e9   梁灏   Modal add mask & ...
172
173
174
175
176
177
178
                      }
                  ];
              },
              contentClasses () {
                  return [
                      `${prefixCls}-content`,
                      {
d4b59a9a   梁灏   Modal add dragabl...
179
                          [`${prefixCls}-content-no-mask`]: !this.showMask,
1210cfe5   梁灏   update Modal prop...
180
181
                          [`${prefixCls}-content-drag`]: this.draggable,
                          [`${prefixCls}-content-dragging`]: this.draggable && this.dragData.dragging
d42d4def   梁灏   Modal add fullscr...
182
183
                      }
                  ];
be966e9f   梁灏   add Modal component
184
              },
6259471f   梁灏   support Modal
185
              mainStyles () {
be966e9f   梁灏   add Modal component
186
187
                  let style = {};
  
f03c4e64   梁灏   Modal update widt...
188
                  const width = parseInt(this.width);
d4b59a9a   梁灏   Modal add dragabl...
189
190
191
                  const styleWidth = this.dragData.x !== null ? {
                      top: 0
                  } : {
f03c4e64   梁灏   Modal update widt...
192
                      width: width <= 100 ? `${width}%` : `${width}px`
be966e9f   梁灏   add Modal component
193
194
                  };
  
6259471f   梁灏   support Modal
195
                  const customStyle = this.styles ? this.styles : {};
be966e9f   梁灏   add Modal component
196
197
198
199
  
                  Object.assign(style, styleWidth, customStyle);
  
                  return style;
e5337c81   梁灏   fixed some compon...
200
              },
d4b59a9a   梁灏   Modal add dragabl...
201
202
203
              contentStyles () {
                  let style = {};
  
1210cfe5   梁灏   update Modal prop...
204
                  if (this.draggable) {
d4b59a9a   梁灏   Modal add dragabl...
205
206
207
208
209
210
211
212
213
214
215
216
                      if (this.dragData.x !== null) style.left = `${this.dragData.x}px`;
                      if (this.dragData.y !== null) style.top = `${this.dragData.y}px`;
                      const width = parseInt(this.width);
                      const styleWidth = {
                          width: width <= 100 ? `${width}%` : `${width}px`
                      };
  
                      Object.assign(style, styleWidth);
                  }
  
                  return style;
              },
e5337c81   梁灏   fixed some compon...
217
218
219
220
221
222
223
224
225
226
227
228
229
              localeOkText () {
                  if (this.okText === undefined) {
                      return this.t('i.modal.okText');
                  } else {
                      return this.okText;
                  }
              },
              localeCancelText () {
                  if (this.cancelText === undefined) {
                      return this.t('i.modal.cancelText');
                  } else {
                      return this.cancelText;
                  }
1c7289e9   梁灏   Modal add mask & ...
230
231
              },
              showMask () {
1210cfe5   梁灏   update Modal prop...
232
                  return this.draggable ? false : this.mask;
be966e9f   梁灏   add Modal component
233
234
235
236
237
              }
          },
          methods: {
              close () {
                  this.visible = false;
6259471f   梁灏   support Modal
238
                  this.$emit('input', false);
be966e9f   梁灏   add Modal component
239
240
                  this.$emit('on-cancel');
              },
1c7289e9   梁灏   Modal add mask & ...
241
242
              handleMask () {
                  if (this.maskClosable && this.showMask) {
be966e9f   梁灏   add Modal component
243
244
245
                      this.close();
                  }
              },
09bce8de   梁灏   update Modal
246
              handleWrapClick (event) {
bb060b98   梁灏   fix #5800, close ...
247
248
249
250
                  if (this.isMouseTriggerIn) {
                      this.isMouseTriggerIn = false;
                      return;
                  }
09bce8de   梁灏   update Modal
251
                  // use indexOf,do not use === ,because ivu-modal-wrap can have other custom className
48dd8ebf   梁灏   update Modal
252
                  const className = event.target.getAttribute('class');
1c7289e9   梁灏   Modal add mask & ...
253
                  if (className && className.indexOf(`${prefixCls}-wrap`) > -1) this.handleMask();
09bce8de   梁灏   update Modal
254
              },
bb060b98   梁灏   fix #5800, close ...
255
256
257
              handleMousedown () {
                  this.isMouseTriggerIn = true;
              },
be966e9f   梁灏   add Modal component
258
259
260
261
262
263
264
265
              cancel () {
                  this.close();
              },
              ok () {
                  if (this.loading) {
                      this.buttonLoading = true;
                  } else {
                      this.visible = false;
6259471f   梁灏   support Modal
266
                      this.$emit('input', false);
be966e9f   梁灏   add Modal component
267
268
269
270
271
272
                  }
                  this.$emit('on-ok');
              },
              EscClose (e) {
                  if (this.visible && this.closable) {
                      if (e.keyCode === 27) {
707a3d82   梁灏   update Modal for ...
273
274
275
276
277
278
279
280
281
                          const $Modals = findComponentsDownward(this.$root, 'Modal').filter(item => item.$data.visible && item.$props.closable);
  
                          const $TopModal = $Modals.sort((a, b) => {
                              return a.$data.modalIndex < b.$data.modalIndex ? 1 : -1;
                          })[0];
  
                          setTimeout(() => {
                              $TopModal.close();
                          }, 0);
be966e9f   梁灏   add Modal component
282
283
284
                      }
                  }
              },
f3454b37   marvinwilliam   add modal hidden ...
285
286
              animationFinish() {
                  this.$emit('on-hidden');
d4b59a9a   梁灏   Modal add dragabl...
287
288
              },
              handleMoveStart (event) {
1210cfe5   梁灏   update Modal prop...
289
                  if (!this.draggable) return false;
d4b59a9a   梁灏   Modal add dragabl...
290
291
292
  
                  const $content = this.$refs.content;
                  const rect = $content.getBoundingClientRect();
e4a967ce   chendawei   fixed: modal drag...
293
294
                  this.dragData.x = rect.x || rect.left;
                  this.dragData.y = rect.y || rect.top;
d4b59a9a   梁灏   Modal add dragabl...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
  
                  const distance = {
                      x: event.clientX,
                      y: event.clientY
                  };
  
                  this.dragData.dragX = distance.x;
                  this.dragData.dragY = distance.y;
  
                  this.dragData.dragging = true;
  
                  on(window, 'mousemove', this.handleMoveMove);
                  on(window, 'mouseup', this.handleMoveEnd);
              },
              handleMoveMove (event) {
                  if (!this.dragData.dragging) return false;
  
                  const distance = {
                      x: event.clientX,
                      y: event.clientY
                  };
  
                  const diff_distance = {
                      x: distance.x - this.dragData.dragX,
                      y: distance.y - this.dragData.dragY
                  };
  
                  this.dragData.x += diff_distance.x;
                  this.dragData.y += diff_distance.y;
  
                  this.dragData.dragX = distance.x;
                  this.dragData.dragY = distance.y;
              },
8750244d   梁灏   update Modal
328
              handleMoveEnd () {
d4b59a9a   梁灏   Modal add dragabl...
329
330
331
                  this.dragData.dragging = false;
                  off(window, 'mousemove', this.handleMoveMove);
                  off(window, 'mouseup', this.handleMoveEnd);
707a3d82   梁灏   update Modal for ...
332
333
334
335
336
337
              },
              handleGetModalIndex () {
                  modalIncrease();
                  return modalIndex;
              },
              handleClickModal () {
7bafe9d9   梁灏   fixes #4453 #4480...
338
339
340
                  if (this.draggable) {
                      this.modalIndex = this.handleGetModalIndex();
                  }
be966e9f   梁灏   add Modal component
341
342
              }
          },
6259471f   梁灏   support Modal
343
          mounted () {
be966e9f   梁灏   add Modal component
344
345
346
347
348
349
              if (this.visible) {
                  this.wrapShow = true;
              }
  
              let showHead = true;
  
2ac208b9   梁灏   fixed #407
350
              if (this.$slots.header === undefined && !this.title) {
be966e9f   梁灏   add Modal component
351
352
353
354
355
356
357
358
359
360
                  showHead = false;
              }
  
              this.showHead = showHead;
  
              // ESC close
              document.addEventListener('keydown', this.EscClose);
          },
          beforeDestroy () {
              document.removeEventListener('keydown', this.EscClose);
727b795c   梁灏   reset body scroll...
361
              this.removeScrollEffect();
be966e9f   梁灏   add Modal component
362
363
          },
          watch: {
6259471f   梁灏   support Modal
364
365
              value (val) {
                  this.visible = val;
6259471f   梁灏   support Modal
366
              },
be966e9f   梁灏   add Modal component
367
368
369
              visible (val) {
                  if (val === false) {
                      this.buttonLoading = false;
e011898c   梁灏   fixed #197
370
                      this.timer = setTimeout(() => {
be966e9f   梁灏   add Modal component
371
                          this.wrapShow = false;
9084eb18   梁灏   fixed #92
372
                          this.removeScrollEffect();
be966e9f   梁灏   add Modal component
373
                      }, 300);
be966e9f   梁灏   add Modal component
374
                  } else {
707a3d82   梁灏   update Modal for ...
375
376
                      this.modalIndex = this.handleGetModalIndex();
  
e011898c   梁灏   fixed #197
377
                      if (this.timer) clearTimeout(this.timer);
be966e9f   梁灏   add Modal component
378
                      this.wrapShow = true;
5d0b89ce   Rijn   change scrolling ...
379
                      if (!this.scrollable) {
f9a2e611   Rijn   added scrolling p...
380
381
                          this.addScrollEffect();
                      }
be966e9f   梁灏   add Modal component
382
                  }
67c9b1c8   梁灏   fixed #591
383
                  this.broadcast('Table', 'on-visible-change', val);
2eccfc99   梁灏   fixed #2852
384
                  this.broadcast('Slider', 'on-visible-change', val);  // #2852
d1f698ca   yangdan8   Modal弹窗请添加on-visi...
385
                  this.$emit('on-visible-change', val);
3c01d81a   梁灏   fixed Modal bug,w...
386
387
388
389
390
              },
              loading (val) {
                  if (!val) {
                      this.buttonLoading = false;
                  }
f9a2e611   Rijn   added scrolling p...
391
              },
5d0b89ce   Rijn   change scrolling ...
392
              scrollable (val) {
f346ce4b   Rijn   lint fix
393
                  if (!val) {
f9a2e611   Rijn   added scrolling p...
394
395
396
397
                      this.addScrollEffect();
                  } else {
                      this.removeScrollEffect();
                  }
f024ab82   H   修复modal标题属性首次如果没有...
398
399
400
              },
              title (val) {
                  if (this.$slots.header === undefined) {
c5625bfd   梁灏   update Modal
401
                      this.showHead = !!val;
f024ab82   H   修复modal标题属性首次如果没有...
402
                  }
be966e9f   梁灏   add Modal component
403
404
              }
          }
b0893113   jingsam   :art: add eslint
405
      };
d6342fe1   jingsam   fixed ie bug
406
  </script>