Skip to content

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

范围:左上角(0,0) / 右下角(1000,600)
Range: Top-left (0, 0) / Bottom-right (1000, 600)
Example code
vue
<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.
vue
<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

状态(Status):隐藏(Hide)




header, body, and footer must be VNode instances; otherwise, they will not be processed.
vue
<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
vue
<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
vue
<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

ParameterDescriptionTypeOptional ValuesDefault Value
model-value / v-modelWhether to display the dialogboolean
widthWidth of the dialogstring-
heightHeight of the dialogstring-
toptop value in the dialog's CSSstring-
resizeWhether the bottom-right corner can be dragged to resizebooleanfalse
dragWhether the dialog is draggablebooleantrue
boundingsDraggable area boundsarray-
custom-classCustom class name for the dialogstring
open-delayDelay time for opening the dialog (milliseconds)number0
close-delayDelay time for closing the dialog (milliseconds)number0
show-closeWhether to display the close buttonbooleantrue
show-maximizeWhether to display the maximize buttonbooleantrue
show-collapseWhether to display the collapse buttonbooleantrue
before-closeCallback before closing; pauses dialog closing. done is used to close the Dialog
animation-nameDialog animation typestring--
titleDialog title (lower priority than the header slot)string--
z-indexCustom z-indexnumber--
idID of the dialog's root nodestring--
use-dockWhether to use with DockContainer. If set to true, the dialog will be stored in DockContainer when collapsed.boolean-false
snapshotThe format to display when used with DockContainerboolean / string / object { type: string, url: string }-false
Panel Component AttributesThe dialog is built based on the Panel component and automatically supports all Panel component attributes.---

Slots

NameDescription
defaultCustom content
headerCustom header
footerCustom footer

Events

Event NameDescriptionCallback Parameter
openCallback when the dialog opens
openedCallback when the dialog's open animation finishes
closeCallback when the dialog closes
closedCallback when the dialog's close animation finishes
resizeCallback when the dialog is resized by draggingDialog DOM root node
maximizeCallback when the dialog is maximized/minimizedWhether maximized
collapseCallback when the dialog is collapsed/expandedWhether collapsed

ModelessDialogManager Methods

MethodDescriptionParameters
showShows 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 }
getGets the dialog instanceDialog ID
hasChecks if the dialog already existsDialog ID
closeAllCloses all dialogs-
showAllShows all dialogs-
hideAllHides all dialogs-
collapseAllCollapses all dialogs-
expandAllExpands all dialogs-

ModelessDialog Instance Methods

MethodDescriptionParameters
closeCloses the dialog-
toggleShowShows/hides the dialogshown: boolean (manually set show or hide)
toggleCollapseCollapses/expands the dialogcollapsable: boolean (manually set collapse or expand)
toggleMaximizeMaximizes/restores the dialogmaximizable: boolean (manually set maximize)
isShownChecks if the dialog is currently shown-
isClosedChecks if the dialog is currently closed-
isCollapsedChecks if the dialog is currently collapsed-
isMaximizedChecks if the dialog is currently maximized-