ModelessDialog
A non-modal dialog based on Panel, supporting features such as maximize, minimize, collapse, expand, and drag to resize.
Basic
You can instantiate this component by declaring it as a component. The component is automatically destroyed after clicking the close button or navigating to a different route.
You can set left
/top
in the style to override the default pop-up position.
<template>
<el-button @click="show">{{ visible ? 'Hide' : 'Show' }}</el-button>
<epp-modeless-dialog v-model="visible" title="非模态对话框示例" resize @resize="resizeCB">
<p>非模态对话框示例</p>
</epp-modeless-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const visible = ref(false);
const show = () => {
visible.value = !visible.value;
};
const resizeCB = () => {
console.log('resizing...');
};
</script>
Dragging Bounds
You can limit the draggable area using the boundings
prop. boundings
is an array of four numbers representing the top-left corner coordinates (x, y) and the bottom-right corner coordinates (x, y).
Example code
<template>
<el-button @click="show">{{ visible ? 'Hide' : 'Show' }}</el-button>
<div class="m-t-md">范围:左上角(0,0) / 右下角(1000,600)</div>
<div class="m-t-md">Range: Top-left (0, 0) / Bottom-right (1000, 600)</div>
<epp-modeless-dialog v-model="visible" width="400px" title="非模态对话框示例" :boundings="[0, 0, 1000, 600]">
<p>非模态对话框示例</p>
</epp-modeless-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const visible = ref(false);
const show = () => {
visible.value = !visible.value;
};
</script>
Using ModelessDialogManager
Create dialogs by calling the show
method of the ModelessDialogManager
API. These dialogs will persist even after page transitions.
The id
prop requires a unique and fixed value.
<template>
<el-space size="large">
<el-button @click="create">创建(Create)</el-button>
<el-button @click="close">手动关闭(Close Manually)</el-button>
</el-space>
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { ElEmpty } from 'element-plus';
import { ModelessDialogManager } from 'element-plus-plus';
const close = () => {
ModelessDialogManager.get('my-modelesss-dialog').close();
};
const create = () => {
ModelessDialogManager.show({
id: 'my-modelesss-dialog',
title: '测试Manager',
body: h(ElEmpty, { description: '空内容' }),
resize: true,
onResize: (dlg: HTMLDivElement) => {
console.log('resize', dlg);
},
onOpen: () => {
console.log('open');
},
onOpened: () => {
console.log('opened');
},
onClose: () => {
console.log('close');
},
onClosed: () => {
console.log('closed');
},
onDestroy: () => {
console.log('destroy');
},
onCollapse: (value: boolean) => {
console.log('collapse', value);
},
onMaximize: (value: boolean) => {
console.log('maximize', value);
},
});
};
</script>
ModelessDialogManager API Example
header
, body
, and footer
must be VNode instances; otherwise, they will not be processed.
<template>
<el-space size="large">
<el-button @click="create">创建(Create)</el-button>
<el-tag>状态(Status):{{ visible ? '显示(Show)' : '隐藏(Hide)' }}</el-tag>
</el-space>
<br /><br />
<el-space size="large">
<el-button @click="max">最大化(Max)</el-button>
<el-button @click="collapse">折叠(Collapse)</el-button>
<el-button @click="show">显示/隐藏(Show/Hide)</el-button>
<el-button @click="close">手工关闭(Close Manually)</el-button>
</el-space>
<hr />
<el-space size="large" class="m-t-lg">
<el-button @click="create2">创建多个对话框(Create Dialogs)</el-button>
</el-space>
<br />
<el-space size="large" class="m-t-lg">
<el-button @click="collaseAll">折叠所有(Collapse All)</el-button>
<el-button @click="closeAll">关闭所有(Close All)</el-button>
<el-button @click="hideAll">隐藏所有(Hide All)</el-button>
<el-button @click="showAll">显示所有(Show All)</el-button>
</el-space>
</template>
<script lang="ts" setup>
import { ref, h } from 'vue';
import { ElButton } from 'element-plus';
import { ModelessDialogManager } from 'element-plus-plus';
const inputVal = ref('');
const visible = ref(false);
const create = () => {
ModelessDialogManager.show({
id: 'my-modelesss-dialog2',
title: '测试Manager,固定ID',
body: h('input', {
value: inputVal.value,
style: 'border: 1px solid #efefef',
onInput: (e: InputEvent) => {
inputVal.value = (e.target as HTMLInputElement).value;
},
}),
footer: h('div', null, [
h(ElButton, { type: 'primary', class: 'm-r-md' }, { default: () => '确定' }),
h(ElButton, null, { default: () => '取消' }),
]),
});
visible.value = ModelessDialogManager.get('my-modelesss-dialog2').isShown();
};
const show = () => {
ModelessDialogManager.get('my-modelesss-dialog2').toggleShow();
visible.value = ModelessDialogManager.get('my-modelesss-dialog2').isShown();
};
const max = () => {
ModelessDialogManager.get('my-modelesss-dialog2').toggleMaximize();
};
const collapse = () => {
ModelessDialogManager.get('my-modelesss-dialog2').toggleCollapse();
};
const close = () => {
ModelessDialogManager.get('my-modelesss-dialog2').close();
};
const create2 = () => {
ModelessDialogManager.show({
title: '测试Manager',
});
};
const collaseAll = () => {
ModelessDialogManager.collapseAll();
};
const closeAll = () => {
ModelessDialogManager.closeAll();
};
const showAll = () => {
ModelessDialogManager.showAll();
};
const hideAll = () => {
ModelessDialogManager.hideAll();
};
</script>
ModelessDialogManager API Reactive Example
If you need to dynamically modify the dialog, you can use reactive
to wrap all properties.
Example code
<template>
<el-space size="large">
<el-button @click="create">创建(Create)</el-button>
<el-button @click="modifyProp">修改对话框属性(Modify properties)</el-button>
</el-space>
<br /><br />
<el-space size="large">
<el-button @click="modifySlot">修改Slot(Modify slot)</el-button>
<el-button @click="modifyPanel">修改Panel属性(Modify panel properties)</el-button>
</el-space>
</template>
<script lang="ts" setup>
import { ref, reactive, h } from 'vue';
import { ElButton } from 'element-plus';
import { ModelessDialogManager } from 'element-plus-plus';
const inputVal = ref('');
const dialogProps = reactive({
id: 'my-modelesss-dialog3',
borderless: true,
bodyPadding: 'var(--lg)',
title: '测试Manager',
body: h('input', {
value: inputVal.value,
onInput: (e: InputEvent) => {
inputVal.value = (e.target as HTMLInputElement).value;
},
}),
footer: h('div', null, [
h(ElButton, { type: 'primary', class: 'm-r-md' }, { default: () => '确定' }),
h(ElButton, null, { default: () => '取消' }),
]),
});
const create = () => {
ModelessDialogManager.show(dialogProps);
};
const modifyProp = () => {
dialogProps.title = '修改对话框标题';
};
const modifySlot = () => {
dialogProps.footer = h('div', { innerHTML: '修改Footer Slot内容' });
};
const modifyPanel = () => {
dialogProps.borderless = false;
dialogProps.bodyPadding = '8px';
};
</script>
Preview Image/Video/Document
- Resizing is possible by dragging the handle at the bottom-right corner.
- Can maximize and minimize the window/dialog.
- The floating window persists across route changes.
Example code
<template>
<el-space size="large">
<el-button @click="create1">图片(Image)</el-button>
<el-button @click="create2">多张图(2x2 Image)</el-button>
<el-button @click="create3">PDF预览(Preview)</el-button>
</el-space>
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { withBase } from 'vitepress';
import { ModelessDialogManager } from 'element-plus-plus';
const create1 = () => {
ModelessDialogManager.show({
customClass: 'example-modeless',
title: '图片预览',
width: '40vw',
height: '30vh',
body: h('div', { class: 'image-example', innerHTML: `<img src="${withBase('/zen.jpg')}" />` }),
resize: true,
onResize: (dlg: HTMLDivElement) => {
console.log('resize', dlg);
},
});
};
const create2 = () => {
ModelessDialogManager.show({
customClass: 'example-modeless2',
title: '图片预览',
width: '40vw',
height: '30vh',
body: h('div', {
class: 'image-example2',
innerHTML: `
<img src="${withBase('/zen.jpg')}" />
<img src="${withBase('/zen.jpg')}" />
<img src="${withBase('/zen.jpg')}" />
<img src="${withBase('/zen.jpg')}" />
`,
}),
resize: true,
onResize: (dlg: HTMLDivElement) => {
console.log('resize', dlg);
},
});
};
const create3 = () => {
ModelessDialogManager.show({
customClass: 'example-modeless3',
title: 'PDF预览',
width: '40vw',
height: '50vh',
body: h('iframe', { class: 'pdf-example', src: `${withBase('/example.pdf')}` }),
resize: true,
});
};
</script>
<style lang="scss">
.example-modeless,
.example-modeless2 {
.panel-body {
height: calc(100% - var(--panel-header-height));
}
}
.example-modeless3 {
.panel-body {
padding: 0;
height: calc(100% - var(--panel-header-height));
}
}
.image-example {
width: 100%;
height: 100%;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.image-example2 {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
gap: 10px;
img {
width: calc(50% - 20px / 2);
height: calc(50% - 20px / 2);
object-fit: cover;
}
}
.pdf-example {
width: 100%;
height: 100%;
}
</style>
Using with DockContainer
Please refer to the DockContainer component documentation.
Attributes
Parameter | Description | Type | Optional Values | Default Value |
---|---|---|---|---|
model-value / v-model | Whether to display the dialog | boolean | — | — |
width | Width of the dialog | string | — | - |
height | Height of the dialog | string | — | - |
top | top value in the dialog's CSS | string | — | - |
resize | Whether the bottom-right corner can be dragged to resize | boolean | — | false |
drag | Whether the dialog is draggable | boolean | — | true |
boundings | Draggable area bounds | array | — | - |
custom-class | Custom class name for the dialog | string | — | — |
open-delay | Delay time for opening the dialog (milliseconds) | number | — | 0 |
close-delay | Delay time for closing the dialog (milliseconds) | number | — | 0 |
show-close | Whether to display the close button | boolean | — | true |
show-maximize | Whether to display the maximize button | boolean | — | true |
show-collapse | Whether to display the collapse button | boolean | — | true |
before-close | Callback before closing; pauses dialog closing. done is used to close the Dialog | — | — | |
animation-name | Dialog animation type | string | - | - |
title | Dialog title (lower priority than the header slot) | string | - | - |
z-index | Custom z-index | number | - | - |
id | ID of the dialog's root node | string | - | - |
use-dock | Whether to use with DockContainer. If set to true , the dialog will be stored in DockContainer when collapsed. | boolean | - | false |
snapshot | The format to display when used with DockContainer | boolean / string / object { type: string, url: string } | - | false |
Panel Component Attributes | The dialog is built based on the Panel component and automatically supports all Panel component attributes. | - | - | - |
Slots
Name | Description |
---|---|
default | Custom content |
header | Custom header |
footer | Custom footer |
Events
Event Name | Description | Callback Parameter |
---|---|---|
open | Callback when the dialog opens | — |
opened | Callback when the dialog's open animation finishes | — |
close | Callback when the dialog closes | — |
closed | Callback when the dialog's close animation finishes | — |
resize | Callback when the dialog is resized by dragging | Dialog DOM root node |
maximize | Callback when the dialog is maximized/minimized | Whether maximized |
collapse | Callback when the dialog is collapsed/expanded | Whether collapsed |
ModelessDialogManager Methods
Method | Description | Parameters |
---|---|---|
show | Shows the dialog. Automatically checks if a dialog with the specified ID exists; if so, returns the existing dialog instance. | Dialog supported attributes & { header: VNode, body: VNode, footer: VNode } |
get | Gets the dialog instance | Dialog ID |
has | Checks if the dialog already exists | Dialog ID |
closeAll | Closes all dialogs | - |
showAll | Shows all dialogs | - |
hideAll | Hides all dialogs | - |
collapseAll | Collapses all dialogs | - |
expandAll | Expands all dialogs | - |
ModelessDialog Instance Methods
Method | Description | Parameters |
---|---|---|
close | Closes the dialog | - |
toggleShow | Shows/hides the dialog | shown: boolean (manually set show or hide) |
toggleCollapse | Collapses/expands the dialog | collapsable: boolean (manually set collapse or expand) |
toggleMaximize | Maximizes/restores the dialog | maximizable: boolean (manually set maximize) |
isShown | Checks if the dialog is currently shown | - |
isClosed | Checks if the dialog is currently closed | - |
isCollapsed | Checks if the dialog is currently collapsed | - |
isMaximized | Checks if the dialog is currently maximized | - |