Commit 707a3d825d7c2ce6a12fed5e72a2df7f73dcbeb2
1 parent
753720d9
update Modal for ESC key, and add prop z-index
Showing
3 changed files
with
54 additions
and
39 deletions
Show diff stats
examples/routers/modal.vue
1 | 1 | <template> |
2 | 2 | <div> |
3 | - <Button @click="instance('info')">Info</Button> | |
4 | - <Button @click="instance('success')">Success</Button> | |
5 | - <Button @click="instance('warning')">Warning</Button> | |
6 | - <Button @click="instance('error')">Error</Button> | |
3 | + <Button @click="modal12 = true">Open the first modal</Button> | |
4 | + <Button @click="modal13 = true">Open the second modal</Button> | |
5 | + <Modal v-model="modal12" draggable scrollable title="Modal 1"> | |
6 | + <div>This is the first modal</div> | |
7 | + </Modal> | |
8 | + <Modal v-model="modal13" draggable scrollable title="Modal 2"> | |
9 | + <div>This is the second modal</div> | |
10 | + </Modal> | |
7 | 11 | </div> |
8 | 12 | </template> |
9 | 13 | <script> |
10 | 14 | export default { |
11 | - methods: { | |
12 | - instance (type) { | |
13 | - const title = 'Title'; | |
14 | - const content = '<p>Content of dialog</p><p>Content of dialog</p>'; | |
15 | - switch (type) { | |
16 | - case 'info': | |
17 | - this.$Modal.info({ | |
18 | - title: title, | |
19 | - content: content | |
20 | - }); | |
21 | - break; | |
22 | - case 'success': | |
23 | - this.$Modal.success({ | |
24 | - title: title, | |
25 | - content: content | |
26 | - }); | |
27 | - break; | |
28 | - case 'warning': | |
29 | - this.$Modal.warning({ | |
30 | - title: title, | |
31 | - content: content | |
32 | - }); | |
33 | - break; | |
34 | - case 'error': | |
35 | - this.$Modal.error({ | |
36 | - title: title, | |
37 | - content: content | |
38 | - }); | |
39 | - break; | |
40 | - } | |
15 | + data () { | |
16 | + return { | |
17 | + modal12: false, | |
18 | + modal13: false | |
41 | 19 | } |
42 | 20 | } |
43 | 21 | } | ... | ... |
src/components/modal/modal.vue
... | ... | @@ -3,10 +3,10 @@ |
3 | 3 | <transition :name="transitionNames[1]"> |
4 | 4 | <div :class="maskClasses" v-show="visible" v-if="showMask" @click="handleMask"></div> |
5 | 5 | </transition> |
6 | - <div :class="wrapClasses" @click="handleWrapClick"> | |
6 | + <div :class="wrapClasses" :style="wrapStyles" @click="handleWrapClick"> | |
7 | 7 | <transition :name="transitionNames[0]" @after-leave="animationFinish"> |
8 | 8 | <div :class="classes" :style="mainStyles" v-show="visible"> |
9 | - <div :class="contentClasses" ref="content" :style="contentStyles"> | |
9 | + <div :class="contentClasses" ref="content" :style="contentStyles" @click="handleClickModal"> | |
10 | 10 | <a :class="[prefixCls + '-close']" v-if="closable" @click="close"> |
11 | 11 | <slot name="close"> |
12 | 12 | <Icon type="ios-close"></Icon> |
... | ... | @@ -38,6 +38,9 @@ |
38 | 38 | import ScrollbarMixins from './mixins-scrollbar'; |
39 | 39 | |
40 | 40 | import { on, off } from '../../utils/dom'; |
41 | + import { findComponentsDownward } from '../../utils/assist'; | |
42 | + | |
43 | + import { modalIndex, modalIncrease } from './q'; | |
41 | 44 | |
42 | 45 | const prefixCls = 'ivu-modal'; |
43 | 46 | |
... | ... | @@ -114,7 +117,11 @@ |
114 | 117 | draggable: { |
115 | 118 | type: Boolean, |
116 | 119 | default: false |
117 | - } | |
120 | + }, | |
121 | + zIndex: { | |
122 | + type: Number, | |
123 | + default: 1000 | |
124 | + }, | |
118 | 125 | }, |
119 | 126 | data () { |
120 | 127 | return { |
... | ... | @@ -129,7 +136,8 @@ |
129 | 136 | dragX: null, |
130 | 137 | dragY: null, |
131 | 138 | dragging: false |
132 | - } | |
139 | + }, | |
140 | + modalIndex: this.handleGetModalIndex(), // for Esc close the top modal | |
133 | 141 | }; |
134 | 142 | }, |
135 | 143 | computed: { |
... | ... | @@ -143,6 +151,11 @@ |
143 | 151 | } |
144 | 152 | ]; |
145 | 153 | }, |
154 | + wrapStyles () { | |
155 | + return { | |
156 | + zIndex: this.modalIndex + this.zIndex | |
157 | + }; | |
158 | + }, | |
146 | 159 | maskClasses () { |
147 | 160 | return `${prefixCls}-mask`; |
148 | 161 | }, |
... | ... | @@ -247,7 +260,15 @@ |
247 | 260 | EscClose (e) { |
248 | 261 | if (this.visible && this.closable) { |
249 | 262 | if (e.keyCode === 27) { |
250 | - this.close(); | |
263 | + const $Modals = findComponentsDownward(this.$root, 'Modal').filter(item => item.$data.visible && item.$props.closable); | |
264 | + | |
265 | + const $TopModal = $Modals.sort((a, b) => { | |
266 | + return a.$data.modalIndex < b.$data.modalIndex ? 1 : -1; | |
267 | + })[0]; | |
268 | + | |
269 | + setTimeout(() => { | |
270 | + $TopModal.close(); | |
271 | + }, 0); | |
251 | 272 | } |
252 | 273 | } |
253 | 274 | }, |
... | ... | @@ -298,6 +319,13 @@ |
298 | 319 | this.dragData.dragging = false; |
299 | 320 | off(window, 'mousemove', this.handleMoveMove); |
300 | 321 | off(window, 'mouseup', this.handleMoveEnd); |
322 | + }, | |
323 | + handleGetModalIndex () { | |
324 | + modalIncrease(); | |
325 | + return modalIndex; | |
326 | + }, | |
327 | + handleClickModal () { | |
328 | + this.modalIndex = this.handleGetModalIndex(); | |
301 | 329 | } |
302 | 330 | }, |
303 | 331 | mounted () { |
... | ... | @@ -332,6 +360,8 @@ |
332 | 360 | this.removeScrollEffect(); |
333 | 361 | }, 300); |
334 | 362 | } else { |
363 | + this.modalIndex = this.handleGetModalIndex(); | |
364 | + | |
335 | 365 | if (this.timer) clearTimeout(this.timer); |
336 | 366 | this.wrapShow = true; |
337 | 367 | if (!this.scrollable) { | ... | ... |