ElDialog
组件 closeOnClickModal
为 true
时,鼠标不管在哪里按下在遮罩层抬起时或鼠标在遮罩层按下不管在哪里抬起时都会关闭遮罩层问题
从 根目录
→ node_modules
→ element-ui
→ packages
→ dialog
→ src
→ component.vue
复制全部代码
在 根目录
→ src
→ components
下创建 ElseDialog
文件夹再创建 index.vue
文件
<template>
<transition
name="dialog-fade"
@after-enter="afterEnter"
@after-leave="afterLeave"
>
<!-- 此处将原来组件中的 @click 替换为 @mousedown 和 @mouseup,如此一来,在遮罩层中 mouseup 时也不会意外触发弹窗的关闭 -->
<!-- 增加scrollbar类名所有弹窗出现滚动条而不是页面出现滚动条 -->
<div
v-show="visible"
class="el-dialog__wrapper scrollbar"
@mousedown="handleWrapperMousedown($event)"
@mouseup="handleWrapperMouseup($event)"
>
<div
role="dialog"
:key="key"
aria-modal="true"
:aria-label="title || 'dialog'"
:class="[
'el-dialog',
{ '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: "ElseDialog",
mixins: [Popup, emitter, Migrating],
props: {
title: {
type: String,
default: "",
},
modal: {
type: Boolean,
default: true,
},
modalAppendToBody: {
type: Boolean,
default: true,
},
appendToBody: {
type: Boolean,
default: false,
},
lockScroll: {
type: Boolean,
default: true,
},
closeOnClickModal: {
type: Boolean,
default: true,
},
closeOnPressEscape: {
type: Boolean,
default: true,
},
showClose: {
type: Boolean,
default: true,
},
width: String,
fullscreen: Boolean,
customClass: {
type: String,
default: "",
},
top: {
type: String,
default: "15vh",
},
beforeClose: Function,
center: {
type: Boolean,
default: false,
},
destroyOnClose: Boolean,
},
data() {
return {
closed: false,
mousedownClassBol: false,
key: 0,
};
},
watch: {
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");
if (this.destroyOnClose) {
this.$nextTick(() => {
this.key++;
});
}
}
},
},
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.",
},
};
},
//增加对应事件
handleWrapperMousedown(e) {
this.mousedownClassBol =
!!e.target.classList.contains("el-dialog__wrapper"); // 判断鼠标按下时是否在遮罩层上
},
handleWrapperMouseup(e) {
if (
!!e.target.classList.contains("el-dialog__wrapper") &&
this.mousedownClassBol
) {
// 判断抬起时是否在遮罩层上并且鼠标按下时也在遮罩层上都在时,触发handleWrapperClick事件
this.mousedownClassBol = false;
this.handleWrapperClick();
}
},
handleWrapperClick() {
if (!this.closeOnClickModal) return;
this.handleClose();
},
handleClose() {
if (typeof this.beforeClose === "function") {
this.beforeClose(this.hide);
} else {
this.hide();
}
},
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");
},
afterEnter() {
this.$emit("opened");
},
afterLeave() {
this.$emit("closed");
},
},
mounted() {
if (this.visible) {
this.rendered = true;
this.open();
if (this.appendToBody) {
document.body.appendChild(this.$el);
}
}
},
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>
element-ui
那么到 main.js
中添加如下代码import Element from 'element-ui' // 全局引入element-ui
import ElseDialog from "@/components/ElseDialog"; // 自定义Dialog组件
// ...
Vue.use(Element, {
size: Cookies.get('size') || 'medium' // set element-ui default size
})
// 全局替换 el-dialog
Vue.component('ElDialog', ElseDialog);