Blame view

src/components/modal/modal.vue 11.9 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
102
              },
              transfer: {
                  type: Boolean,
                  default: true
d42d4def   梁灏   Modal add fullscr...
103
104
105
106
              },
              fullscreen: {
                  type: Boolean,
                  default: false
1c7289e9   梁灏   Modal add mask & ...
107
108
109
110
111
112
113
114
              },
              mask: {
                  type: Boolean,
                  default: true
              },
              dragable: {
                  type: Boolean,
                  default: false
be966e9f   梁灏   add Modal component
115
116
117
118
119
120
121
              }
          },
          data () {
              return {
                  prefixCls: prefixCls,
                  wrapShow: false,
                  showHead: true,
6259471f   梁灏   support Modal
122
                  buttonLoading: false,
d4b59a9a   梁灏   Modal add dragabl...
123
124
125
126
127
128
129
130
                  visible: this.value,
                  dragData: {
                      x: null,
                      y: null,
                      dragX: null,
                      dragY: null,
                      dragging: false
                  }
b0893113   jingsam   :art: add eslint
131
              };
be966e9f   梁灏   add Modal component
132
133
134
135
136
137
138
          },
          computed: {
              wrapClasses () {
                  return [
                      `${prefixCls}-wrap`,
                      {
                          [`${prefixCls}-hidden`]: !this.wrapShow,
1c7289e9   梁灏   Modal add mask & ...
139
140
                          [`${this.className}`]: !!this.className,
                          [`${prefixCls}-no-mask`]: !this.showMask
be966e9f   梁灏   add Modal component
141
                      }
b0893113   jingsam   :art: add eslint
142
                  ];
be966e9f   梁灏   add Modal component
143
144
145
146
147
              },
              maskClasses () {
                  return `${prefixCls}-mask`;
              },
              classes () {
d42d4def   梁灏   Modal add fullscr...
148
149
150
151
152
153
                  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 & ...
154
155
156
157
158
159
160
                      }
                  ];
              },
              contentClasses () {
                  return [
                      `${prefixCls}-content`,
                      {
d4b59a9a   梁灏   Modal add dragabl...
161
162
163
                          [`${prefixCls}-content-no-mask`]: !this.showMask,
                          [`${prefixCls}-content-drag`]: this.dragable,
                          [`${prefixCls}-content-dragging`]: this.dragable && this.dragData.dragging
d42d4def   梁灏   Modal add fullscr...
164
165
                      }
                  ];
be966e9f   梁灏   add Modal component
166
              },
6259471f   梁灏   support Modal
167
              mainStyles () {
be966e9f   梁灏   add Modal component
168
169
                  let style = {};
  
f03c4e64   梁灏   Modal update widt...
170
                  const width = parseInt(this.width);
d4b59a9a   梁灏   Modal add dragabl...
171
172
173
                  const styleWidth = this.dragData.x !== null ? {
                      top: 0
                  } : {
f03c4e64   梁灏   Modal update widt...
174
                      width: width <= 100 ? `${width}%` : `${width}px`
be966e9f   梁灏   add Modal component
175
176
                  };
  
6259471f   梁灏   support Modal
177
                  const customStyle = this.styles ? this.styles : {};
be966e9f   梁灏   add Modal component
178
179
180
181
  
                  Object.assign(style, styleWidth, customStyle);
  
                  return style;
e5337c81   梁灏   fixed some compon...
182
              },
d4b59a9a   梁灏   Modal add dragabl...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
              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...
199
200
201
202
203
204
205
206
207
208
209
210
211
              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 & ...
212
213
214
              },
              showMask () {
                  return this.dragable ? false : this.mask;
be966e9f   梁灏   add Modal component
215
216
217
218
219
              }
          },
          methods: {
              close () {
                  this.visible = false;
6259471f   梁灏   support Modal
220
                  this.$emit('input', false);
be966e9f   梁灏   add Modal component
221
222
                  this.$emit('on-cancel');
              },
1c7289e9   梁灏   Modal add mask & ...
223
224
              handleMask () {
                  if (this.maskClosable && this.showMask) {
be966e9f   梁灏   add Modal component
225
226
227
                      this.close();
                  }
              },
09bce8de   梁灏   update Modal
228
229
              handleWrapClick (event) {
                  // use indexOf,do not use === ,because ivu-modal-wrap can have other custom className
48dd8ebf   梁灏   update Modal
230
                  const className = event.target.getAttribute('class');
1c7289e9   梁灏   Modal add mask & ...
231
                  if (className && className.indexOf(`${prefixCls}-wrap`) > -1) this.handleMask();
09bce8de   梁灏   update Modal
232
              },
be966e9f   梁灏   add Modal component
233
234
235
236
237
238
239
240
              cancel () {
                  this.close();
              },
              ok () {
                  if (this.loading) {
                      this.buttonLoading = true;
                  } else {
                      this.visible = false;
6259471f   梁灏   support Modal
241
                      this.$emit('input', false);
be966e9f   梁灏   add Modal component
242
243
244
245
246
247
                  }
                  this.$emit('on-ok');
              },
              EscClose (e) {
                  if (this.visible && this.closable) {
                      if (e.keyCode === 27) {
b0893113   jingsam   :art: add eslint
248
                          this.close();
be966e9f   梁灏   add Modal component
249
250
251
                      }
                  }
              },
f3454b37   marvinwilliam   add modal hidden ...
252
253
              animationFinish() {
                  this.$emit('on-hidden');
d4b59a9a   梁灏   Modal add dragabl...
254
255
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
              },
              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
295
              handleMoveEnd () {
d4b59a9a   梁灏   Modal add dragabl...
296
297
298
                  this.dragData.dragging = false;
                  off(window, 'mousemove', this.handleMoveMove);
                  off(window, 'mouseup', this.handleMoveEnd);
be966e9f   梁灏   add Modal component
299
300
              }
          },
6259471f   梁灏   support Modal
301
          mounted () {
be966e9f   梁灏   add Modal component
302
303
304
305
306
307
              if (this.visible) {
                  this.wrapShow = true;
              }
  
              let showHead = true;
  
2ac208b9   梁灏   fixed #407
308
              if (this.$slots.header === undefined && !this.title) {
be966e9f   梁灏   add Modal component
309
310
311
312
313
314
315
316
317
318
                  showHead = false;
              }
  
              this.showHead = showHead;
  
              // ESC close
              document.addEventListener('keydown', this.EscClose);
          },
          beforeDestroy () {
              document.removeEventListener('keydown', this.EscClose);
727b795c   梁灏   reset body scroll...
319
              this.removeScrollEffect();
be966e9f   梁灏   add Modal component
320
321
          },
          watch: {
6259471f   梁灏   support Modal
322
323
              value (val) {
                  this.visible = val;
6259471f   梁灏   support Modal
324
              },
be966e9f   梁灏   add Modal component
325
326
327
              visible (val) {
                  if (val === false) {
                      this.buttonLoading = false;
e011898c   梁灏   fixed #197
328
                      this.timer = setTimeout(() => {
be966e9f   梁灏   add Modal component
329
                          this.wrapShow = false;
9084eb18   梁灏   fixed #92
330
                          this.removeScrollEffect();
be966e9f   梁灏   add Modal component
331
                      }, 300);
be966e9f   梁灏   add Modal component
332
                  } else {
e011898c   梁灏   fixed #197
333
                      if (this.timer) clearTimeout(this.timer);
be966e9f   梁灏   add Modal component
334
                      this.wrapShow = true;
5d0b89ce   Rijn   change scrolling ...
335
                      if (!this.scrollable) {
f9a2e611   Rijn   added scrolling p...
336
337
                          this.addScrollEffect();
                      }
be966e9f   梁灏   add Modal component
338
                  }
67c9b1c8   梁灏   fixed #591
339
                  this.broadcast('Table', 'on-visible-change', val);
2eccfc99   梁灏   fixed #2852
340
                  this.broadcast('Slider', 'on-visible-change', val);  // #2852
d1f698ca   yangdan8   Modal弹窗请添加on-visi...
341
                  this.$emit('on-visible-change', val);
3c01d81a   梁灏   fixed Modal bug,w...
342
343
344
345
346
              },
              loading (val) {
                  if (!val) {
                      this.buttonLoading = false;
                  }
f9a2e611   Rijn   added scrolling p...
347
              },
5d0b89ce   Rijn   change scrolling ...
348
              scrollable (val) {
f346ce4b   Rijn   lint fix
349
                  if (!val) {
f9a2e611   Rijn   added scrolling p...
350
351
352
353
                      this.addScrollEffect();
                  } else {
                      this.removeScrollEffect();
                  }
f024ab82   H   修复modal标题属性首次如果没有...
354
355
356
              },
              title (val) {
                  if (this.$slots.header === undefined) {
c5625bfd   梁灏   update Modal
357
                      this.showHead = !!val;
f024ab82   H   修复modal标题属性首次如果没有...
358
                  }
be966e9f   梁灏   add Modal component
359
360
              }
          }
b0893113   jingsam   :art: add eslint
361
      };
d6342fe1   jingsam   fixed ie bug
362
  </script>