English
FxDialog
About 2157 wordsAbout 7 min
2025-12-16
Informs the user and carries related actions while preserving the current page state.
Basic Usage
Dialog pops up a dialog and is suitable for scenarios that require more customization.
All Popover layers are managed uniformly. You can get the latest zIndex value through FxUI.Utils.getPopupZIndex().
<fx-button type="primary" @click="handlerClick" ref="btn1"
>dialog default</fx-button
>
<!-- <fx-button type="primary" @click="dialogVisible1_2=true">dialog small</fx-button> -->
<!-- <fx-button type="primary" @click="dialogVisible1_3=true">dialog medium</fx-button> -->
<fx-button type="primary" @click="dialogVisible1_4=true"
>dialog witdh:30%</fx-button
>
<fx-button type="primary" @click="dialogVisible1_5=true"
>dialog fullscreen</fx-button
>
<div>Current zIndex:{{popupZIndex}}</div>
<fx-dialog
:visible.sync="dialogVisible"
ref="dialog1"
:append-to-body="true"
title="Tip1"
z-index="3000"
max-height="200px"
@open="open"
@opened="opened"
@close="close"
@closed="closed"
>
<template v-for="item in arr">
<span>This is a message{{item}}</span> <br />
</template>
<span slot="footer" class="dialog-footer">
<fx-button @click="dialogVisible = false">Cancel</fx-button>
<fx-button type="primary" @click="arr.length=20">Confirm</fx-button>
</span>
<fx-dropdown>
<span class="el-dropdown-link">
Dropdown Menu<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<fx-dropdown-menu slot="dropdown" z-index="1000">
<fx-dropdown-item>Golden cake</fx-dropdown-item>
<fx-dropdown-item>Lion head meatball</fx-dropdown-item>
<fx-dropdown-item>Luosifen</fx-dropdown-item>
<fx-dropdown-item disabled>Double-skin milk</fx-dropdown-item>
<fx-dropdown-item divided>Oyster omelet</fx-dropdown-item>
</fx-dropdown-menu>
</fx-dropdown>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible1_2"
ref="dialog1_2"
size="small"
:append-to-body="true"
title="Tip"
max-height="300px"
:before-close="handleClose"
@opened="opened"
>
<template v-for="item in arr">
<span>This is a message2-{{item}}</span> <br />
</template>
<span slot="footer" class="dialog-footer">
<fx-button size="small" @click="dialogVisible1_2 = false">Cancel</fx-button>
<fx-button size="small" type="primary" @click="dialogVisible1_2 = false"
>Confirm</fx-button
>
</span>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible1_3"
ref="dialog1_3"
size="medium"
:append-to-body="true"
title="Tip"
@opened="opened"
>
<span>This is a message3</span> <br />
<span slot="footer" class="dialog-footer">
<fx-button @click="dialogVisible1_3 = false">Cancel</fx-button>
<fx-button type="primary" @click="dialogVisible1_3 = false"
>Confirm</fx-button
>
</span>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible1_4"
ref="dialog1_4"
width="30%"
:append-to-body="true"
title="Tip"
@opened="opened"
>
<template v-for="item in arr">
<span>This is a message4-{{item}}</span> <br />
</template>
<span slot="footer" class="dialog-footer">
<fx-button @click="dialogVisible1_4 = false">Cancel</fx-button>
<fx-button type="primary" @click="dialogVisible1_4 = false"
>Confirm</fx-button
>
</span>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible1_5"
ref="dialog1_5"
fullscreen
size="small"
:append-to-body="true"
title="Tip"
@opened="opened"
>
<span>This is message 5</span> <br />
<span>This is message 5</span> <br />
<span>This is message 5</span> <br />
<span>This is message 5</span> <br />
<span slot="footer" class="dialog-footer">
<fx-button @click="dialogVisible1_5 = false">Cancel</fx-button>
<fx-button type="primary" @click="dialogVisible1_5 = false"
>Confirm</fx-button
>
</span>
</fx-dialog>
<script>
export default {
data() {
return {
popupZIndex: 2000,
arr: [],
dialogVisible: false,
dialogVisible1_2: false,
dialogVisible1_3: false,
dialogVisible1_4: false,
dialogVisible1_5: false
};
},
watch: {
dialogVisible1_4(val) {
setTimeout(() => {
this.arr = [];
for (let i = 0; i < 20; i++) {
this.arr.push(i);
}
this.$refs.dialog1_4.caculatePosition();
setTimeout(() => {
for (let i = 0; i < 20; i++) {
this.arr.push(i);
}
this.$refs.dialog1_4.caculatePosition();
}, 2000);
}, 2000);
}
},
methods: {
handlerClick() {
this.dialogVisible = true;
// FxUI.Utils.updatePopupZIndex(3000);
},
handleClose(done) {
this.$confirm("Confirm close?")
.then(_ => {
done();
})
.catch(_ => {});
},
open() {
console.log("open....");
},
opened() {
console.log("opened....");
// this.popupZIndex = this.$FxUI.Utils.getPopupZIndex();
},
close() {
console.log("close....");
},
closed() {
console.log("closed....");
}
},
created() {
for (let i = 0; i < 100; i++) {
this.arr.push(i);
}
}
};
</script>Tips
before-close only takes effect when the user closes Dialog by clicking the close icon or mask. If you add a button for closing Dialog in the named footer slot, add the related before-close logic in the button click callback.
Slide Panel
<fx-button type="text" @click="dialogVisible1 = true"
>Click to open Dialog1</fx-button
>
<fx-button type="text" @click="dialogVisible2 = true"
>Click to open Dialog2</fx-button
>
<fx-dialog
ref="dialog1"
title="Tip"
:visible.sync="dialogVisible1"
width="50%"
:append-to-body="true"
:slider-panel="true"
:modal="false"
@open="open"
@opened="opened"
@closed="closed"
>
<span>This is a message</span>
<fx-button type="text" @click="dialogVisible1_1=true"
>Click to open Dialog</fx-button
>
<fx-menu default-active="1" class="el-menu-demo" mode="horizontal">
<fx-menu-item index="1">Processing Center</fx-menu-item>
<fx-submenu index="2">
<template slot="title">My Workspace</template>
<fx-menu-item index="2-1">Option 1</fx-menu-item>
<fx-menu-item index="2-2">Option 2</fx-menu-item>
<fx-menu-item index="2-3">Option 3</fx-menu-item>
<fx-submenu index="2-4">
<template slot="title">Option 4</template>
<fx-menu-item index="2-4-1">Option 1</fx-menu-item>
<fx-menu-item index="2-4-2">Option 2</fx-menu-item>
<fx-menu-item index="2-4-3">Option 3</fx-menu-item>
</fx-submenu>
</fx-submenu>
<fx-menu-item index="3" disabled>Info Center</fx-menu-item>
</fx-menu>
</fx-dialog>
<fx-dialog
ref="dialog1"
title="Tip"
:visible.sync="dialogVisible1_1"
width="50%"
:append-to-body="true"
:slider-panel="true"
:modal="false"
>
<span>This is a message</span>
<fx-button type="text" @click="dialogVisible1_2=true"
>Click to open Dialog</fx-button
>
</fx-dialog>
<fx-dialog
ref="dialog1"
title="Tip"
:visible.sync="dialogVisible1_2"
width="50%"
:append-to-body="true"
:slider-panel="true"
:modal="false"
>
<span>This is a message</span>
<fx-button type="text" @click="onClick">Click to open Dialog</fx-button>
</fx-dialog>
<fx-dialog
title="Tip2"
:visible.sync="dialogVisible2"
width="30%"
:append-to-body="true"
:slider-panel="true"
>
<span>This is a message</span>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible3"
:append-to-body="true"
title="Tip1"
max-height="200px"
>
<span>This is a message</span>
</fx-dialog>
<script>
export default {
data() {
return {
dialogVisible1: false,
dialogVisible1_1: false,
dialogVisible1_2: false,
dialogVisible2: false,
dialogVisible3: false,
styleObj: {
top: "30px"
}
};
},
methods: {
onClick() {
this.dialogVisible3 = true;
// let index = this.$FxUI.Utils.getPopupZIndex();
// console.log(21222,this.$refs.dialog1,index)
},
open() {
console.log("open....");
},
opened() {
console.log("opened....");
},
close() {
console.log("close....");
},
closed() {
console.log("closed....");
}
},
created() {}
};
</script>Custom Content
Dialog component content can be arbitrary, even a Table or Form. The following are two examples using Element Table and Form components.
<!-- Table -->
<fx-button type="text" @click="dialogTableVisible = true"
>Open Dialog with nested Table</fx-button
>
<fx-dialog title="Shipping Address" :visible.sync="dialogTableVisible">
<fx-table :data="gridData">
<fx-table-column property="date" label="Date" width="150"></fx-table-column>
<fx-table-column property="name" label="Name" width="200"></fx-table-column>
<fx-table-column property="address" label="Address"></fx-table-column>
</fx-table>
</fx-dialog>
<!-- Form -->
<fx-button type="text" @click="dialogFormVisible = true"
>Open Dialog with nested Form</fx-button
>
<fx-dialog title="Shipping Address" :visible.sync="dialogFormVisible">
<fx-form :model="form">
<fx-form-item label="Activity Name" :labfx-width="formLabelWidth">
<fx-input v-model="form.name" autocomplete="off"></fx-input>
</fx-form-item>
</fx-form>
<div slot="footer" class="dialog-footer">
<fx-button @click="dialogFormVisible = false">Cancel</fx-button>
<fx-button type="primary" @click="dialogFormVisible = false"
>Confirm</fx-button
>
</div>
</fx-dialog>
<script>
export default {
data() {
return {
gridData: [
{
date: "2016-05-02",
name: "Wang Xiaohu",
address: "Lane 1518, Jinshajiang Road, Putuo District, Shanghai"
},
{
date: "2016-05-04",
name: "Wang Xiaohu",
address: "Lane 1518, Jinshajiang Road, Putuo District, Shanghai"
},
{
date: "2016-05-01",
name: "Wang Xiaohu",
address: "Lane 1518, Jinshajiang Road, Putuo District, Shanghai"
},
{
date: "2016-05-03",
name: "Wang Xiaohu",
address: "Lane 1518, Jinshajiang Road, Putuo District, Shanghai"
}
],
dialogTableVisible: false,
dialogFormVisible: false,
form: {
name: "",
region: "",
date1: "",
date2: "",
delivery: false,
type: [],
resource: "",
desc: ""
},
formLabelWidth: "120px"
};
}
};
</script>Nested Dialog
If you need to nest one Dialog inside another Dialog, use the append-to-body property.
<template>
<fx-button type="text" @click="outerVisible = true"
>Click to open outer Dialog</fx-button
>
<fx-dialog title="Outer Dialog" :visible.sync="outerVisible">
<fx-dialog
width="30%"
title="Inner Dialog"
:visible.sync="innerVisible"
append-to-body
>
</fx-dialog>
<div slot="footer" class="dialog-footer">
<fx-button @click="outerVisible = false">Cancel</fx-button>
<fx-button type="primary" @click="innerVisible = true"
>Open inner Dialog</fx-button
>
</div>
</fx-dialog>
</template>
<script>
export default {
data() {
return {
outerVisible: false,
innerVisible: false
};
}
};
</script>Centered Layout
Title and footer can be horizontally centered.
<fx-button type="text" @click="centerDialogVisible = true"
>Click to open Dialog</fx-button
>
<fx-dialog title="Tip" :visible.sync="centerDialogVisible" width="30%" center>
<span>Note that the content is not centered by default</span>
<span slot="footer" class="dialog-footer">
<fx-button @click="centerDialogVisible = false">Cancel</fx-button>
<fx-button type="primary" @click="centerDialogVisible = false"
>Confirm</fx-button
>
</span>
</fx-dialog>
<script>
export default {
data() {
return {
centerDialogVisible: false
};
}
};
</script>Tips
Dialog content is lazily rendered. Before it is opened for the first time, the passed default slot is not rendered to the DOM. Therefore, if you need to perform DOM actions or obtain the corresponding component through ref, do so in the open event callback.
Tips
If the variable bound to the visible property is in the Vuex store, .sync will not work correctly. Remove the .sync modifier, listen to the open and close events of Dialog, and update the value bound to the visible property by executing the corresponding Vuex mutation in the event callback.
Attributes
| Parameter | Description | Type | Optional Values | Default | PC/Mobile Support |
|---|---|---|---|---|---|
| visible/v-model | Whether to show Dialog; supports the .sync modifier | boolean | - | false | PC only supports visible / Mobile only supports v-model |
| title | Dialog title. It can also be passed through a named slot (see the table below) | string | - | - | PC only |
| width | Dialog width | string | - | 50% | PC only |
| max-height | Maximum height of the Dialog body, such as "200px" | string | - | - | PC only |
| fullscreen | Whether Dialog is fullscreen | boolean | - | false | PC only |
| modal | Whether a mask is required | boolean | - | true | PC/Mobile |
| modal-append-to-body | Whether the mask is appended to the body element. If false, the mask is appended to Dialog parent element | boolean | - | true | PC only |
| append-to-body | Whether Dialog itself is appended to the body element. Nested Dialogs must specify this property and set it to true | boolean | - | false | PC only |
| lock-scroll | Whether to lock body scrolling when Dialog appears | boolean | - | true | PC only |
| custom-class | Custom class name of Dialog | string | - | - | PC/Mobile |
| close-on-press-escape | Whether Dialog can be closed by pressing ESC | boolean | - | true | PC only |
| show-close | Whether to show the close button, provided that title is not empty or there is a slot equal to header | boolean | - | true | PC only |
| before-close | Callback before close; pauses Dialog closing | function(done), done is used to close Dialog | - | - | PC/Mobile |
| center | Whether to use centered layout for the header and footer | boolean | - | false | PC only |
| autoClose | Whether to close automatically | boolean | - | - | PC only |
| duration | Auto-close delay, unit: ms | number | - | 3000 | PC only |
| sliderPanel | Whether it is a slide panel. Default width is 50% of the screen | boolean | - | false | PC only |
| close-on-click-outside | When sliderPanel is true, whether dialog can be closed by clicking outside Dialog | boolean | - | true | PC/Mobile |
| transition | Animation mode | String | fade/ slide/ scale/ shrink | fade | Mobile only |
| remove-modal | Whether to remove the mask DOM | Boolean | - | false | Mobile only |
| close-when-popstate | Listens to popstate events and closes popup and modal when the route changes | Boolean | - | true | Mobile only |
Slot
| name | Description | PC/Mobile Support |
|---|---|---|
| - | Dialog content | PC/Mobile |
| title | Content of the Dialog title area | PC only |
| footer | Content of the Dialog button action area | PC only |
Methods
| Method | Description | Parameter | PC/Mobile Support |
|---|---|---|---|
| caculatePosition | Recalculates dialog position. Available when content changes. | - | PC only |
Events
| Event Name | Description | Callback Parameters | PC/Mobile Support |
|---|---|---|---|
| open | Callback when Dialog opens | - | PC only |
| opened | Callback after the Dialog open animation ends | - | PC only |
| close | Callback when Dialog closes | - | PC only |
| closed | Callback after the Dialog close animation ends | - | PC/Mobile |
| update:visible | Callback when visible updates | - | PC only |
| click-modal | Triggered when clicking the mask | - | Mobile only |
