Vue.js 로 JS의 Confirm함수 구현한 boiler code (feat.Promise)

강정우·2023년 10월 14일
0

vue.js

목록 보기
67/72
post-thumbnail
post-custom-banner

Vue.js로 JS의 Confirm함수 구현하기

  • 아래코드는 <base-confrim> 이라는 Confirm 함수를 구현한 코드이다.

  • 어떨 때 쓰면되냐면 수정팝업에서 확인 버튼 클릭후 확인 reaction 모달과 수정 팝업을 함께 지울 때 쓰거나
    사용자가 확인을 누른 후 라우팅을 넘기고싶을 때 사용하면 된다.

<base-confrim>

<template>
    <teleport to="body">
        <div v-if="props.show" @click="tryClose" class="backdrop"></div>
        <transition name="popUp">
            <div v-if="props.show" class="modalAlert">
                <div class="popTitle center">
                    <span>{{props.title}}</span>
                    <span class="right" style="padding-right: 20px">
                        <span class="btnExitPop" @click="tryClose">
                            <img src="../../images/btnExit2.png"/>
                        </span>
                    </span>
                </div>
                <div style="padding: 10px">
                    <div class="popSubBox" style="display: flex; justify-content: center">
                        <slot name="content"></slot>
                    </div>
                </div>
                <div style="display: flex; justify-content: center">
                    <base-btn cmpclass="btnNormal" title="확인" @click="tryEvent"></base-btn>
                    <base-btn cmpclass="btnNormal" title="취소" @click="tryClose"></base-btn>
                </div>
            </div>
        </transition>
    </teleport>
</template>
<script setup>
import BaseBtn from "@/components/ui/BaseBtn.vue";
import {defineProps, defineEmits} from "vue";

const props = defineProps({
    show:{
        type: Boolean,
        required: true,
    },
    title: {
        type: String,
        required: false,
    },
})

const emits = defineEmits(['close','event'])

const tryClose = () => {
    return new Promise((resolve) => {
        emits('close')
        resolve();
    });
}

const tryEvent = () => {
    return new Promise((resolve) => {
        emits('event')
        resolve();
    });
}
</script>

  • 위 <base-confirm> 컴포넌트가 사용되면 위와 같이 생겼다.

마크업 컴포넌트

<base-confirm :show="!!needOK" title="알림" ref="confirm" @event="ok" @close="no">
  <template #content>
    <p>{{needOK}}</p>
  </template>
</base-confirm>

마크업 컴포넌트의 <script setup>

const ok = async () => {
    await router.push('log-in')
}
const no = () => {
    needOK.value = null;
}
const openConfirm = async () => {
    try {
        const params = {name:findName.value, email:findEmail.value, phone:findPhone.value}
        await store.dispatch('findId', params);
        needOK.value='회원님의 아이디는" '+foundUserId.value+' "입니다.'
        // needOk에 값을 넣으면 이제 ok함수 또는 on함수의 결과를 Promise로 받고 다음 로직이 실행됨.
    }catch (e) {
        error.value = '일치하는 회원이 없습니다.'
    }
    store.commit('initFoundUserId');
};

참고

<template>
  <div v-if="isOpen" class="base-confirm">
    <div class="base-confirm-overlay"></div>
    <div class="base-confirm-dialog">
      <div class="base-confirm-content">
        <slot></slot>
      </div>
      <div class="base-confirm-actions">
        <button @click="handleConfirm">OK</button>
        <button @click="handleCancel">Cancel</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isOpen: false,
      resolveFunc: null,
      rejectFunc: null
    };
  },
  methods: {
    open() {
      this.isOpen = true;
      return new Promise((resolve, reject) => {
        this.resolveFunc = resolve;
        this.rejectFunc = reject;
      });
    },
    close() {
      this.isOpen = false;
    },
    handleConfirm() {
      this.close();
      this.resolveFunc();
    },
    handleCancel() {
      this.close();
      this.rejectFunc();
    }
  }
};
</script>
  • 위 코드는 단순히 promise 객채를 갖고 실행하는 코드이고 위 코드를 generic하게 쓰일려면 resolve, reject에 해당하는 함수를 emits으로 받아와서 data 옵션을 대신하면 된다.
<template>
  <div>
    <button @click="showConfirm">Show Confirm</button>
    <base-confirm ref="confirmDialog">
      <p>Are you sure?</p>
    </base-confirm>
  </div>
</template>

<script>
import BaseConfirm from '@/components/BaseConfirm.vue';

export default {
  components: {
    BaseConfirm
  },
  methods: {
    async showConfirm() {
      try {
        await this.$refs.confirmDialog.open();
        // User clicked OK
        console.log('Confirmed');
      } catch (error) {
        // User clicked Cancel
        console.log('Cancelled');
      }
    }
  }
};
</script>
  • 또한 위 로직을 사용할 때 $refs를 이용하여 함수를 사용해도 되고 혹은
const {open} = confirmDialog
  • 이런식으로 구조분해를 하여 가져와도 된다. 그리고 open함수는 promise를 return할 것이고 promise 객체는 반드시 .then() 혹은 async/await과 함께 쓰여야한다.
profile
智(지)! 德(덕)! 體(체)!
post-custom-banner

0개의 댓글