1、index.vue
<template>
<!-- :z-index="zIndex" -->
<el-dialog :custom-class="className" :class="{
'has-icon': hasIcon,
'has-border': hasBorder
}" :visible="visible" :width="width+'px'" :title="title" @close="$emit('close')">
<div class="content-box">
<slot>
<template v-if="hasIcon">
<i class="el-icon-warning"></i>
<div class="title">{{title}}</div>
</template>
<div class="content">{{content}}</div>
</slot>
</div>
<el-row type="flex" justify="center" slot="footer">
<el-button type="primary" @click="$emit('success')">确认</el-button>
<el-button type="default" @click="$emit('close')">取消</el-button>
</el-row>
</el-dialog>
</template>
<script>
export default {
props: {
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: '提示'
},
// 是否有警告图标
hasIcon: {
type: Boolean,
default: true
},
// 是否有头部底部线
hasBorder: {
type: Boolean,
default: false
},
width: {
type: Number,
default: 500
},
// zIndex: {
// type: Number,
// default: 3000
// }
},
components: {},
data() {
return {
className: 'confirm-dialog',
content: ''
};
},
created() {},
mounted() {
console.log('this', this);
},
methods: {},
watch: {
},
computed: {}
};
</script>
<style lang="scss">
.el-dialog__wrapper {
&.has-icon {
.el-dialog__title {
display: none;
}
.el-dialog__headerbtn {
top: 10px;
}
.el-dialog__body {
padding-top: 0px;
}
.content-box {
align-items: center;
flex-direction: column;
i {
font-size: 28px;
color: #f67922;
}
.title {
color: #0e0e0f;
font-size: 18px;
font-weight: 700;
margin-top: 5px;
}
.content {
color: #5e5f61;
font-size: 14px;
margin-top: 10px;
}
}
}
&.has-border {
.el-dialog__header {
border-bottom: 1px solid #EBECED;
}
.el-dialog__footer {
border-top: 1px solid #EBECED;
}
}
}
.confirm-dialog {
.el-dialog__header {
padding: 14px 32px;
}
.el-dialog__title {
color: #0e0e0f;
font-size: 18px;
font-weight: 700;
}
.column-center {
align-items: center;
display: flex;
justify-content: center;
flex-direction: column;
}
.red-tip {
color: #ff0000;
}
.el-button {
width: 60px;
height: 32px;
// line-height: 60px;
padding: 0px;
}
.el-button--primary{
background: #3065FF;
}
.el-button--default{
color: #0E0E0F;
border: 1px solid #D9DADB;
&:hover{
color: #0E0E0F;
border: 1px solid #D9DADB;
background-color: #fff;
}
}
}
</style>
<style lang="scss" scoped>
.content-box {
display: flex;
justify-content: center;
}
.color-red {
color: #d8696b;
}
</style>
2、组件index.js
import confirmDialog from "./index.vue";
import dialog from "./dialog";
function install(Vue) {
Vue.prototype.$confirmDialog = function (options) {
return dialog(confirmDialog, {
visible: true,
...options,
});
};
Vue.prototype.$dialog = dialog;
}
export default {
install,
};
3、 dialog.js
import Vue from "vue";
import { isVNode } from "element-ui/src/utils/vdom";
let instance = null;
export default function (Component, options) {
let DialogConstructor = Vue.extend(Component);
// console.log(propsData)
if (!instance) {
instance = new DialogConstructor({
el: document.createElement("div"),
});
for (let prop in options) {
if (options.hasOwnProperty(prop)) {
instance[prop] = options[prop];
}
}
if (isVNode(instance.content)) {
instance.$slots.default = [instance.content];
instance.content = null;
} else {
delete instance.$slots.default;
}
document.body.appendChild(instance.$el);
Vue.nextTick(() => {
instance.visible = true;
});
function close() {
if (!instance) return;
instance.$nextTick(() => {
if (!instance) return;
instance.$destroy(true);
if (instance.$el.parentNode) {
instance.$el.parentNode.removeChild(instance.$el);
}
instance = null;
});
}
return new Promise((resolve, reject) => {
let onClose = () => {
instance.visible = false;
reject();
close();
};
let onSuccess = (data) => {
resolve(data);
close();
};
instance.$on("close", onClose);
instance.$on("cancel", onClose);
instance.$on("success", onSuccess);
instance.$on("enter", onSuccess);
});
} else {
return Promise.reject(new Error("请先关闭对话框"));
}
}
4、在main.js中注册
import ConfirmDialog from "@/components/ConfirmDialog";
Vue.use(ConfirmDialog);
5、使用示例
await this.$confirmDialog({
visible: true,
title: '提示',
content: '修改暂计量比例,当前数据会重置,确认是否继续?'
});
6、实际效果