使用vue與promise的知識來封裝一個好用的confirm!!
知識重點
我們都知道回傳一個promise物件的時後可以使用resolve來執行then與reject來執行catch。
所以我用一個promiseStatus把resolve與reject兩個函式記下來,之後再按下確認的button觸發resolve,取消的時候觸發reject。
使用方法
template裡面引入 <Confirm ref="confirm" />
js中使用 this.$refs.confirm.show(`錯誤:${StatusCode}`, "確認","取消").then(成功的func).catch(取消的func)
範例Confirm.vue
<template>
<transition name="slide-fade">
<div
v-if="isOpen"
class="confirm-cover"
>
<div class="confirm rounded shadow">
<div class="border-bottom pb-2">
{{ title }}
<i
v-show="title === '確認框'"
class="ml-1 fas fa-exclamation-circle text-danger"
/>
</div>
<slot />
<div
v-if="!$slots.default"
class="text-break confirm-message d-flex align-items-center justify-content-center"
v-html="message"
/>
<div class="d-flex justify-content-center border-top pt-2 button-group">
<button
v-if="trueMessage"
class="btn"
:class="'btn-'+trueClass"
@click="clickHandler(true)"
>
{{ trueMessage }}
</button>
<button
v-if="falseMessage"
class="btn btn-"
:class="'btn-'+falseClass"
@click="clickHandler(false)"
>
{{ falseMessage }}
</button>
</div>
</div>
</div>
</transition>
</template>
<script>
export default {
props:{
title:{
type:String,
default:"確認框(Confirm Box)"
}
},
data() {
return {
isOpen: false,
message: "無訊息",
trueMessage: "確認(Confirm)",
falseMessage: "取消(Cancel)",
trueClass:"outline-primary",
falseClass:"outline-dark",
promiseStatus: null,
};
},
methods: {
show(message, trueMessage, falseMessage,trueClass='outline-primary',falseClass='outline-dark') {
this.isOpen = true;
this.message = message;
this.trueMessage = trueMessage;
this.falseMessage = falseMessage;
this.trueClass=trueClass
this.falseClass=falseClass
return new Promise((resolve, reject) => {
this.promiseStatus = { resolve, reject };
});
},
clickHandler(action) {
this.isOpen = false;
if (action) {
this.promiseStatus && this.promiseStatus.resolve();
} else {
this.promiseStatus && this.promiseStatus.reject();
}
},
},
};
</script>
<style lang="scss">
.confirm-cover {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 999;
font-size: 16px;
.confirm {
position: absolute;
top: 200px;
left: 50%;
padding: 0.75rem 1rem;
position: absolute;
left: 50%;
top: 100px;
transform: translateX(-50%);
background-color: #fff;
width: 300px;
}
.confirm-message {
min-height: 100px;
}
.fas.fa-times-circle {
position: absolute;
right: 1rem;
}
.button-group{
button + button{
margin-left: 10px;
}
}
}
</style>