用vue封裝一個confirm吧!!

使用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>