在Vue项目中实现一个可直接使用js调用的confirm弹框组件
- 实现dialog组件
<template>
<van-overlay :show="visible" class-name="dialog-overlay flex-center">
<div class="dialog">
<div class="dialog-container bg-fff width-590 radius-16 flex-start-column">
<div class="title flex-center" v-if="title">
<img v-if="isShowIcon" class="tips-icon m-r-10" src="@/assets/service/tishi.png" />
<div>{{ title }}</div>
</div>
<div class="content">{{ message }}</div>
<div class="html" v-html="htmlContent"></div>
<div class="footer">
<div class="btn-group" v-if="!isSingle">
<div class="btn cancel" @click="cancel">{{ cancelButtonText }}</div>
<div class="btn confirm" @click="confirm">{{ confirmButtonText }}</div>
</div>
<div class="btn-group" v-else>
<div class="single" @click="confirm">{{ confirmButtonText }}</div>
</div>
</div>
</div>
</div>
</van-overlay>
</template>
<script>
export default {
name: "c-dialog",
data() {
return {
visible: false,
title: "", // 标题
message: "",
htmlContent: "",
confirmButtonText: "确定",
cancelButtonText: "取消",
isSingle: false, // 是否单按钮
isShowIcon: false, // 是否展示提示icon
resolve: null,
reject: null
};
},
methods: {
open(options) {
this.title = options.title || this.title;
this.message = options.message || this.message;
this.htmlContent = options.htmlContent || this.htmlContent;
this.confirmButtonText = options.confirmButtonText || this.confirmButtonText;
this.cancelButtonText = options.cancelButtonText || this.cancelButtonText;
this.isSingle = options.isSingle || this.isSingle;
this.isShowIcon = options.isShowIcon || this.isShowIcon;
this.visible = true;
return new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
},
close() {
this.cancel();
},
cancel() {
this.reject();
this.visible = false;
},
confirm() {
this.resolve();
this.visible = false;
}
}
};
</script>
<style lang="less" scoped>
.dialog {
margin: 0 auto;
.dialog-container {
align-items: center;
padding: 40px 40px 56px;
}
.title {
height: 44px;
font-size: 32px;
font-weight: 600;
color: #0a0707;
line-height: 44px;
font-family: PingFangSC-Medium, PingFang SC;
}
.tips-icon {
width: 28px;
height: 28px;
}
.content {
font-size: 28px;
color: #000000;
line-height: 60px;
margin-top: 40px;
font-weight: 400;
text-align: center;
}
.footer {
margin-top: 60px;
.btn-group {
display: flex;
justify-content: center;
align-items: center;
}
.btn {
width: 240px;
height: 80px;
line-height: 80px;
border-radius: 16px;
border: 2px solid #609e39;
text-align: center;
}
.cancel {
color: #609e39;
}
.confirm {
background: #609e39;
color: #fff;
margin-left: 30px;
}
.single {
width: 324px;
height: 80px;
line-height: 80px;
background: #609e39;
color: #fff;
border-radius: 40px;
text-align: center;
}
}
}
.dialog-overlay {
z-index: 3000;
}
</style>
- 实现install和uninstall方法
import Vue from "vue";
import CDialog from "./index.vue";
import router from "@/router";
const DialogConstructor = Vue.extend(CDialog);
const cDialogPlugin = {
install(Vue) {
const instance = new DialogConstructor();
instance.$mount(document.createElement("div"));
document.body.appendChild(instance.$el);
Vue.prototype.$cDialog = {
open(options) {
return instance.open(options);
},
close() {
if (instance && instance.visible) {
instance.close();
}
}
};
},
uninstall(Vue) {
Vue.prototype.$cDialog = null;
}
};
router.afterEach(() => {
Vue.prototype.$cDialog && Vue.prototype.$cDialog.close();
});
export default cDialogPlugin;
- 全局或局部注册
main.js
import CDialog from "@/components/c-dialog/index";
Vue.use(CDialog);