<template>
<transition
name="dialog-fade"
@after-enter="afterEnter"
@after-leave="afterLeave">
<div class="el-dialog__wrapper" v-show="visible" @click.self="handleWrapperClick">
<div
role="dialog"
aria-modal="true"
:aria-label="title || 'dialog'"
class="el-dialog"
:class="[{ 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
ref="dialog"
:style="style">
<div class="el-dialog__header">
<slot name="title">
<span class="el-dialog__title">{{ title }}</span>
</slot>
<button
type="button"
class="el-dialog__headerbtn"
aria-label="Close"
v-if="showClose"
@click="handleClose">
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</div>
<div class="el-dialog__body" v-if="rendered"><slot></slot></div>
<div class="el-dialog__footer" v-if="$slots.footer">
<slot name="footer"></slot>
</div>
</div>
</div>
</transition>
</template>
<script>
import Popup from 'element-ui/src/utils/popup';
import Migrating from 'element-ui/src/mixins/migrating';
import emitter from 'element-ui/src/mixins/emitter';
export default {
name: 'ElDialog',
mixins: [Popup, emitter, Migrating],
props: {
// Dialog 的标题,也可通过具名 slot (见下表)传入
title: {
type: String,
default: ''
},
// modal 是否需要遮罩层
modal: {
type: Boolean,
default: true
},
// 遮罩层是否插入至 body 元素上,若为 false,则遮罩层会插入至 Dialog 的父元素上
modalAppendToBody: {
type: Boolean,
default: true
},
// Dialog 自身是否插入至 body 元素上。嵌套的 Dialog 必须指定该属性并赋值为 true
appendToBody: {
type: Boolean,
default: false
},
// lock-scroll 是否在 Dialog 出现时将 body 滚动锁定
lockScroll: {
type: Boolean,
default: true
},
// close-on-click-modal 是否可以通过点击 modal 关闭 Dialog
closeOnClickModal: {
type: Boolean,
default: true
},
// close-on-press-escape 是否可以通过按下 ESC 关闭 Dialog
closeOnPressEscape: {
type: Boolean,
default: true
},
// show-close 是否显示关闭按钮
showClose: {
type: Boolean,
default: true
},
// width Dialog 的宽度
width: String,
// fullscreen 是否为全屏 Dialog
fullscreen: Boolean,
// custom-class Dialog 的自定义类名
customClass: {
type: String,
default: ''
},
// top Dialog CSS 中的 margin-top 值
top: {
type: String,
default: '15vh'
},
// before-close 关闭前的回调,会暂停 Dialog 的关闭
beforeClose: Function,
// center 是否对头部和底部采用居中布局
center: {
type: Boolean,
default: false
}
},
data() {
return {
closed: false
};
},
watch: {
// 是否显示 Dialog,支持 .sync 修饰符
visible(val) {
if (val) {
this.closed = false;
this.$emit('open');
this.$el.addEventListener('scroll', this.updatePopper);
this.$nextTick(() => {
this.$refs.dialog.scrollTop = 0;
});
if (this.appendToBody) {
document.body.appendChild(this.$el);
}
} else {
this.$el.removeEventListener('scroll', this.updatePopper);
if (!this.closed) this.$emit('close');
}
}
},
computed: {
style() {
let style = {};
if (!this.fullscreen) {
style.marginTop = this.top;
if (this.width) {
style.width = this.width;
}
}
return style;
}
},
methods: {
// 暂时没发现这个什么用
getMigratingConfig() {
return {
props: {
'size': 'size is removed.'
}
};
},
// 点击dialog自身
handleWrapperClick() {
if (!this.closeOnClickModal) return;
this.handleClose();
},
// 关闭dialog
handleClose() {
// 如果有beforeClose,执行beforeClose
if (typeof this.beforeClose === 'function') {
this.beforeClose(this.hide);
} else {
// 否则隐藏
this.hide();
}
},
// 隐藏dialog
hide(cancel) {
if (cancel !== false) {
this.$emit('update:visible', false);
this.$emit('close');
this.closed = true;
}
},
updatePopper() {
this.broadcast('ElSelectDropdown', 'updatePopper');
this.broadcast('ElDropdownMenu', 'updatePopper');
},
// Dialog 打开动画结束时的回调
afterEnter() {
this.$emit('opened');
},
// Dialog 关闭动画结束时的回调
afterLeave() {
this.$emit('closed');
}
},
mounted() {
if (this.visible) {
this.rendered = true;
this.open();
if (this.appendToBody) {
document.body.appendChild(this.$el);
}
}
},
// 销毁前移除dom
destroyed() {
// if appendToBody is true, remove DOM node after destroy
if (this.appendToBody && this.$el && this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el);
}
}
};
</script>