简体中文
FxDialog
约 2681 字大约 9 分钟
2025-12-16
在保留当前页面状态的情况下,告知用户并承载相关操作。
基本用法
Dialog 弹出一个对话框,适合需要定制性更大的场景。
所有弹框层级是统一维护的,可以通过 FxUI.Utils.getPopupZIndex()获取最新 zIndex 值。
<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>当前的zIndex:{{popupZIndex}}</div>
<fx-dialog
:visible.sync="dialogVisible"
ref="dialog1"
:append-to-body="true"
title="提示1"
z-index="3000"
max-height="200px"
@open="open"
@opened="opened"
@close="close"
@closed="closed"
>
<template v-for="item in arr">
<span>这是一段信息{{item}}</span> <br />
</template>
<span slot="footer" class="dialog-footer">
<fx-button @click="dialogVisible = false">取 消</fx-button>
<fx-button type="primary" @click="arr.length=20">确 定</fx-button>
</span>
<fx-dropdown>
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<fx-dropdown-menu slot="dropdown" z-index="1000">
<fx-dropdown-item>黄金糕</fx-dropdown-item>
<fx-dropdown-item>狮子头</fx-dropdown-item>
<fx-dropdown-item>螺蛳粉</fx-dropdown-item>
<fx-dropdown-item disabled>双皮奶</fx-dropdown-item>
<fx-dropdown-item divided>蚵仔煎</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="提示"
max-height="300px"
:before-close="handleClose"
@opened="opened"
>
<template v-for="item in arr">
<span>这是一段信息2-{{item}}</span> <br />
</template>
<span slot="footer" class="dialog-footer">
<fx-button size="small" @click="dialogVisible1_2 = false">取 消</fx-button>
<fx-button size="small" type="primary" @click="dialogVisible1_2 = false"
>确 定</fx-button
>
</span>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible1_3"
ref="dialog1_3"
size="medium"
:append-to-body="true"
title="提示"
@opened="opened"
>
<span>这是一段信息3</span> <br />
<span slot="footer" class="dialog-footer">
<fx-button @click="dialogVisible1_3 = false">取 消</fx-button>
<fx-button type="primary" @click="dialogVisible1_3 = false"
>确 定</fx-button
>
</span>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible1_4"
ref="dialog1_4"
width="30%"
:append-to-body="true"
title="提示"
@opened="opened"
>
<template v-for="item in arr">
<span>这是一段信息4-{{item}}</span> <br />
</template>
<span slot="footer" class="dialog-footer">
<fx-button @click="dialogVisible1_4 = false">取 消</fx-button>
<fx-button type="primary" @click="dialogVisible1_4 = false"
>确 定</fx-button
>
</span>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible1_5"
ref="dialog1_5"
fullscreen
size="small"
:append-to-body="true"
title="提示"
@opened="opened"
>
<span>这是一段信息5</span> <br />
<span>这是一段信息5</span> <br />
<span>这是一段信息5</span> <br />
<span>这是一段信息5</span> <br />
<span slot="footer" class="dialog-footer">
<fx-button @click="dialogVisible1_5 = false">取 消</fx-button>
<fx-button type="primary" @click="dialogVisible1_5 = false"
>确 定</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("确认关闭?")
.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>提示
before-close 仅当用户通过点击关闭图标或遮罩关闭 Dialog 时起效。如果您在 footer 具名 slot 里添加了用于关闭 Dialog 的按钮,那么可以在按钮的点击回调函数里加入 before-close 的相关逻辑。
侧滑框
<fx-button type="text" @click="dialogVisible1 = true"
>点击打开 Dialog1</fx-button
>
<fx-button type="text" @click="dialogVisible2 = true"
>点击打开 Dialog2</fx-button
>
<fx-dialog
ref="dialog1"
title="提示"
:visible.sync="dialogVisible1"
width="50%"
:append-to-body="true"
:slider-panel="true"
:modal="false"
@open="open"
@opened="opened"
@closed="closed"
>
<span>这是一段信息</span>
<fx-button type="text" @click="dialogVisible1_1=true"
>点击打开 Dialog</fx-button
>
<fx-menu default-active="1" class="el-menu-demo" mode="horizontal">
<fx-menu-item index="1">处理中心</fx-menu-item>
<fx-submenu index="2">
<template slot="title">我的工作台</template>
<fx-menu-item index="2-1">选项1</fx-menu-item>
<fx-menu-item index="2-2">选项2</fx-menu-item>
<fx-menu-item index="2-3">选项3</fx-menu-item>
<fx-submenu index="2-4">
<template slot="title">选项4</template>
<fx-menu-item index="2-4-1">选项1</fx-menu-item>
<fx-menu-item index="2-4-2">选项2</fx-menu-item>
<fx-menu-item index="2-4-3">选项3</fx-menu-item>
</fx-submenu>
</fx-submenu>
<fx-menu-item index="3" disabled>消息中心</fx-menu-item>
</fx-menu>
</fx-dialog>
<fx-dialog
ref="dialog1"
title="提示"
:visible.sync="dialogVisible1_1"
width="50%"
:append-to-body="true"
:slider-panel="true"
:modal="false"
>
<span>这是一段信息</span>
<fx-button type="text" @click="dialogVisible1_2=true"
>点击打开 Dialog</fx-button
>
</fx-dialog>
<fx-dialog
ref="dialog1"
title="提示"
:visible.sync="dialogVisible1_2"
width="50%"
:append-to-body="true"
:slider-panel="true"
:modal="false"
>
<span>这是一段信息</span>
<fx-button type="text" @click="onClick">点击打开 Dialog</fx-button>
</fx-dialog>
<fx-dialog
title="提示2"
:visible.sync="dialogVisible2"
width="30%"
:append-to-body="true"
:slider-panel="true"
>
<span>这是一段信息</span>
</fx-dialog>
<fx-dialog
:visible.sync="dialogVisible3"
:append-to-body="true"
title="提示1"
max-height="200px"
>
<span>这是一段信息</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>自定义内容
Dialog 组件的内容可以是任意的,甚至可以是表格或表单,下面是应用了 Element Table 和 Form 组件的两个样例。
<!-- Table -->
<fx-button type="text" @click="dialogTableVisible = true"
>打开嵌套表格的 Dialog</fx-button
>
<fx-dialog title="收货地址" :visible.sync="dialogTableVisible">
<fx-table :data="gridData">
<fx-table-column property="date" label="日期" width="150"></fx-table-column>
<fx-table-column property="name" label="姓名" width="200"></fx-table-column>
<fx-table-column property="address" label="地址"></fx-table-column>
</fx-table>
</fx-dialog>
<!-- Form -->
<fx-button type="text" @click="dialogFormVisible = true"
>打开嵌套表单的 Dialog</fx-button
>
<fx-dialog title="收货地址" :visible.sync="dialogFormVisible">
<fx-form :model="form">
<fx-form-item label="活动名称" :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">取 消</fx-button>
<fx-button type="primary" @click="dialogFormVisible = false"
>确 定</fx-button
>
</div>
</fx-dialog>
<script>
export default {
data() {
return {
gridData: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
}
],
dialogTableVisible: false,
dialogFormVisible: false,
form: {
name: "",
region: "",
date1: "",
date2: "",
delivery: false,
type: [],
resource: "",
desc: ""
},
formLabelWidth: "120px"
};
}
};
</script>嵌套的 Dialog
如果需要在一个 Dialog 内部嵌套另一个 Dialog,需要使用 append-to-body 属性。
<template>
<fx-button type="text" @click="outerVisible = true"
>点击打开外层 Dialog</fx-button
>
<fx-dialog title="外层 Dialog" :visible.sync="outerVisible">
<fx-dialog
width="30%"
title="内层 Dialog"
:visible.sync="innerVisible"
append-to-body
>
</fx-dialog>
<div slot="footer" class="dialog-footer">
<fx-button @click="outerVisible = false">取 消</fx-button>
<fx-button type="primary" @click="innerVisible = true"
>打开内层 Dialog</fx-button
>
</div>
</fx-dialog>
</template>
<script>
export default {
data() {
return {
outerVisible: false,
innerVisible: false
};
}
};
</script>居中布局
标题和底部可水平居中
<fx-button type="text" @click="centerDialogVisible = true"
>点击打开 Dialog</fx-button
>
<fx-dialog title="提示" :visible.sync="centerDialogVisible" width="30%" center>
<span>需要注意的是内容是默认不居中的</span>
<span slot="footer" class="dialog-footer">
<fx-button @click="centerDialogVisible = false">取 消</fx-button>
<fx-button type="primary" @click="centerDialogVisible = false"
>确 定</fx-button
>
</span>
</fx-dialog>
<script>
export default {
data() {
return {
centerDialogVisible: false
};
}
};
</script>提示
Dialog 的内容是懒渲染的,即在第一次被打开之前,传入的默认 slot 不会被渲染到 DOM 上。因此,如果需要执行 DOM 操作,或通过 ref 获取相应组件,请在 open 事件回调中进行。
提示
如果 visible 属性绑定的变量位于 Vuex 的 store 内,那么 .sync 不会正常工作。此时需要去除 .sync 修饰符,同时监听 Dialog 的 open 和 close 事件,在事件回调中执行 Vuex 中对应的 mutation 更新 visible 属性绑定的变量的值。
Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | PC/移动端支持情况 |
|---|---|---|---|---|---|
| visible/v-model | 是否显示 Dialog,支持 .sync 修饰符 | boolean | — | false | PC端仅支持visible/移动端仅支持v-model |
| title | Dialog 的标题,也可通过具名 slot (见下表)传入 | string | — | — | 仅PC |
| width | Dialog 的宽度 | string | — | 50% | 仅PC |
| max-height | Dialog 的 body 部分的最高宽度,如“200px” | string | — | - | 仅PC |
| fullscreen | 是否为全屏 Dialog | boolean | — | false | 仅PC |
| modal | 是否需要遮罩层 | boolean | — | true | PC/移动端 |
| modal-append-to-body | 遮罩层是否插入至 body 元素上,若为 false,则遮罩层会插入至 Dialog 的父元素上 | boolean | — | true | 仅PC |
| append-to-body | Dialog 自身是否插入至 body 元素上。嵌套的 Dialog 必须指定该属性并赋值为 true | boolean | — | false | 仅PC |
| lock-scroll | 是否在 Dialog 出现时将 body 滚动锁定 | boolean | — | true | 仅PC |
| custom-class | Dialog 的自定义类名 | string | — | — | PC/移动端 |
| close-on-press-escape | 是否可以通过按下 ESC 关闭 Dialog | boolean | — | true | 仅PC |
| show-close | 是否显示关闭按钮,前提是 title 不为空或有等于 header 的插槽 | boolean | — | true | 仅PC |
| before-close | 关闭前的回调,会暂停 Dialog 的关闭 | function(done),done 用于关闭 Dialog | — | — | PC/移动端 |
| center | 是否对头部和底部采用居中布局 | boolean | — | false | 仅PC |
| autoClose | 是否自动关闭 | boolean | — | - | 仅PC |
| duration | 自动关闭的延迟时间,单位:ms | number | — | 3000 | 仅PC |
| sliderPanel | 是否是侧滑窗口,默认宽度为屏幕 50% | boolean | — | false | 仅PC |
| close-on-click-outside | sliderPanel 为 true 时,是否可以通过点击 Dialog 之外的区域关闭 dialog | boolean | — | true | PC/移动端 |
| transition | 动画模式 | String | fade/ slide/ scale/ shrink | fade | 仅移动端 |
| remove-modal | 是否移除蒙层DOM | Boolean | - | false | 仅移动端 |
| close-when-popstate | 监听popstate事件,当路由切换时关闭popup及modal | Boolean | - | true | 仅移动端 |
Slot
| name | 说明 | PC/移动端支持情况 |
|---|---|---|
| — | Dialog 的内容 | PC/移动端 |
| title | Dialog 标题区的内容 | 仅PC |
| footer | Dialog 按钮操作区的内容 | 仅PC |
Methods
| 方法名 | 说明 | 参数 | PC/移动端支持情况 |
|---|---|---|---|
| caculatePosition | 重新计算 dialog 位置。当内容有变化时,可用。 | — | 仅PC |
Events
| 事件名称 | 说明 | 回调参数 | PC/移动端支持情况 |
|---|---|---|---|
| open | Dialog 打开的回调 | — | 仅PC |
| opened | Dialog 打开动画结束时的回调 | — | 仅PC |
| close | Dialog 关闭的回调 | — | 仅PC |
| closed | Dialog 关闭动画结束时的回调 | — | PC/移动端 |
| update:visible | visible 更新时的回调 | — | 仅PC |
| click-modal | 点击蒙层时触发 | — | 仅移动端 |
