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) { | ... | ... |