fix(dialog): fix/dialog-close-event (#1164)

* fix(dialog): fix/dialog-close-event

- Dialog now emits close event correctly

* fix overlay render error
This commit is contained in:
jeremywu 2020-12-31 14:33:17 +08:00 committed by GitHub
parent 03a7aa806e
commit cc8f825715
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 8 deletions

View File

@ -230,5 +230,32 @@ describe('Dialog.vue', () => {
await nextTick()
expect(wrapper.find('.el-dialog__body').exists()).toBe(false)
})
test('should emit close event', async () => {
let visible = true
const onClose = jest.fn()
const onClosed = jest.fn()
const wrapper = _mount({
props: {
modelValue: visible,
'onUpdate:modelValue': (val: boolean) => visible = val,
onClose,
onClosed,
},
})
expect(wrapper.vm.visible).toBe(true)
await nextTick()
await rAF()
await nextTick()
await wrapper.find('.el-overlay').trigger('click')
await nextTick()
await rAF()
await nextTick()
expect(onClose).toHaveBeenCalled()
expect(onClosed).toHaveBeenCalled()
expect(visible).toBe(false)
})
})
})

View File

@ -4,6 +4,7 @@
name="dialog-fade"
@after-enter="afterEnter"
@after-leave="afterLeave"
@before-leave="beforeLeave"
>
<el-overlay
v-show="visible"

View File

@ -1,4 +1,4 @@
import { computed, ref, watch, nextTick, onMounted, CSSProperties } from 'vue'
import { computed, ref, watch, nextTick, onMounted } from 'vue'
import isServer from '@element-plus/utils/isServer'
import { UPDATE_MODEL_EVENT } from '@element-plus/utils/constants'
@ -6,7 +6,7 @@ import PopupManager from '@element-plus/utils/popup-manager'
import { clearTimer } from '@element-plus/utils/util'
import { useLockScreen, useRestoreActive, useModal } from '@element-plus/hooks'
import type { Ref } from 'vue'
import type { Ref, CSSProperties } from 'vue'
import type { SetupContext } from '@vue/runtime-core'
import type { UseDialogProps } from './dialog'
@ -49,6 +49,10 @@ export default function(props: UseDialogProps, ctx: SetupContext, targetRef: Ref
}
}
function beforeLeave() {
ctx.emit(CLOSE_EVENT)
}
function open() {
clearTimer(closeTimer)
clearTimer(openTimer)
@ -139,9 +143,8 @@ export default function(props: UseDialogProps, ctx: SetupContext, targetRef: Ref
})
} else {
// this.$el.removeEventListener('scroll', this.updatePopper
close()
if (!closed.value) {
ctx.emit(CLOSE_EVENT)
if (visible.value) {
close()
}
}
})
@ -157,6 +160,7 @@ export default function(props: UseDialogProps, ctx: SetupContext, targetRef: Ref
return {
afterEnter,
afterLeave,
beforeLeave,
handleClose,
onModalClick,
closed,

View File

@ -88,9 +88,12 @@ describe('Drawer', () => {
})
test('should open and close drawer properly', async () => {
const onClose = jest.fn()
const onClosed = jest.fn()
const onOpened = jest.fn()
const wrapper = _mount(
`
<el-drawer :title='title' v-model='visible'>
<el-drawer :title='title' v-model='visible' @closed="onClosed" @close="onClose" @opened="onOpened">
<span>${content}</span>
</el-drawer>
`,
@ -98,18 +101,34 @@ describe('Drawer', () => {
title,
visible: false,
}),
{
methods: {
onOpened,
onClose,
onClosed,
},
},
)
const vm = wrapper.vm as any
await nextTick()
await rAF()
await nextTick()
expect(onOpened).not.toHaveBeenCalled()
const drawerEl = wrapper.find('.el-overlay').element as HTMLDivElement
expect(drawerEl.style.display).toEqual('none')
vm.visible = true
await nextTick()
await rAF()
expect(drawerEl.style.display).not.toEqual('none')
expect(onOpened).toHaveBeenCalled()
// vm.visible = false
// await nextTick()
// await rAF()
// await nextTick()
// expect(onClose).toHaveBeenCalled()
})
test('should destroy every child after drawer was closed when destroy-on-close flag is true', async () => {

View File

@ -4,6 +4,7 @@
name="el-drawer-fade"
@after-enter="afterEnter"
@after-leave="afterLeave"
@before-leave="beforeLeave"
>
<el-overlay
v-show="visible"

View File

@ -42,5 +42,9 @@ describe('Overlay.vue', () => {
mask: false,
})
expect(wrapper.find(selector).exists()).toBe(false)
await wrapper.setProps({
mask: true,
})
expect(wrapper.find(selector).exists()).toBe(true)
})
})

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { createVNode, defineComponent, renderSlot } from 'vue'
import { createVNode, defineComponent, renderSlot, h } from 'vue'
import { PatchFlags } from '@element-plus/utils/vnode'
export default defineComponent({
@ -23,6 +23,8 @@ export default defineComponent({
}
// init here
return () => {
// when the vnode meets the same structure but with different change trigger
// it will not automatically update, thus we simply use h function to manage updating
return props.mask
? createVNode(
'div',
@ -37,7 +39,16 @@ export default defineComponent({
PatchFlags.STYLE | PatchFlags.CLASS | PatchFlags.PROPS,
['onClick'],
)
: renderSlot(slots, 'default')
: h('div', {
style: {
zIndex: props.zIndex,
position: 'fixed',
top: '0px',
right: '0px',
bottom: '0px',
left: '0px',
},
}, [renderSlot(slots, 'default')])
}
},
})