Blame view

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