Blame view

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