element plus版本:2.3.0
需求:在childName子组件中点击按钮,关闭他所在的ElMessageBox,可以怎么实现?
也就说除了消息弹出框自带的关闭按钮等,可以在子组件中获取ElMessageBox实例,通过调用ElMessageBox实例的方法来关闭消息弹出框么?
最终使用的方案4。
已经尝试过的方案:
- 直接调用ElMessageBox.close();会关闭当前打开的所有消息弹出框。
- 通过消息弹出框的class找到它的dom元素,手动移除消息弹出框的dom。可以实现,但是并不想使用这种方法
- 评论中给出的options对象上的onVanish()方案
子组件中通过getCurrentInstance获取到当前实例,再获取父实例。但是要四层$parent才能调用到源码里的doClose方法
<template> <el-button plain @click="open">Common VNode</el-button> <el-button plain @click="open1">Dynamic props</el-button> </template> <script lang="ts" setup> import { h, ref } from 'vue' import { ElMessageBox, ElSwitch } from 'element-plus' import ChildName from './ChildName.vue' const open = () => { ElMessageBox({ title: 'Message', message: h(ChildName, { options: () => options }), }) } const open1 = () => { const checked = ref<boolean | string | number>(false) ElMessageBox({ title: 'Message', // Should pass a function if VNode contains dynamic props message: () => h(ElSwitch, { modelValue: checked.value, 'onUpdate:modelValue': (val: boolean | string | number) => { checked.value = val }, }), }) } </script>
子组件ChildName.vue的代码
<template>
<div>
子组件的内容
<el-button @click="handleHide">
自定义关闭关闭
</el-button>
</div>
</template>
<script lang="tsx">
import {
defineComponent,getCurrentInstance,
} from 'vue'
import { ElButton, ElMessage } from 'element-plus'
export default defineComponent({
name: 'ChildName',
components: {
ElButton,
},
props: {
options: {
type: Function,
default: () => {},
},
},
setup (props: any) {
const instance = getCurrentInstance() as any
const { proxy } = instance
// 关闭弹窗
const handleHide = () => {
// 方案3,但是不太合适
// props.options()?.onVanish()
// 方案4
proxy.$parent.$parent.$parent.$parent.handleClose()
}
return {
handleHide,
}
},
})
</script>
补充:四层$parent的原因是:父组件引用子组件的时候还在外面套了多层 UI 组件。
子组件ChildName的$parent是Element Plus的组件el-focus;
$parent.$parent是Element Plus的组件el-overlay;
$parent.$parent.$parent是Element Plus的组件transtion;
$parent.$parent.$parent.$parent才是ElMessageBox组件。
最终采用的方案4。
通过getCurrentInstance获取当前的ChildName实例对象,然后依次获取其父组件实例,直到获取到ElMessageBox实例对象。调用其handClose方法进行消息弹出框的关闭。