상황
기본모달 - 닫기, 열기 버튼이 Modal 공용 컴포넌트에 있는 경우
Footer가 있는 모달 - 닫기 버튼이 Modal을 실행하는 컴포넌트 밖에 있는 경우
MODAL공용컴포넌트.vue
<script setup lang="ts">
import type { IModalProps } from '~/types/modal'
import { MODAL_SIZE } from '~/types/modal'
const props = withDefaults(defineProps<IModalProps>(), {
title: '',
size: '',
closeOnClickModal: true,
confirmText: '확인',
cancelText: '취소',
})
const emit = defineEmits<{
(e: 'update:modelValue', modelValue: boolean): void
(e: 'cancel'): void
(e: 'confirm'): void
}>()
const modalShow = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
},
})
const cancel = () => {
emit('cancel')
}
const confirm = () => {
emit('confirm')
}
</script>
<template>
<div>
<el-dialog
v-model="modalShow"
:width="calculateModalWidth"
align-center
:before-close="cancel"
:close-on-click-modal="closeOnClickModal"
destroy-on-close
>
<template v-if="title.length" #header>
<span class="modal__title"> {{ title }} </span>
</template>
<slot name="content" />
<template #footer>
<slot name="footer">
<button type="button" class="btn__primary-line btn--lg" @click="cancel"> // 여기는 기본 modal 컴포넌트의 닫기 버튼임
// click 함수를 실행하면 cancel이라는 인자값을 전달함
{{ props.cancelText }}
</button>
<button type="button" class="btn__search" @click="confirm">
{{ props.confirmText }}
</button>
</slot>
</template>
</el-dialog>
</div>
</template>
<style scoped></style>
모달을 사용하는 상위컴포넌트
<script setup lang="ts">
const titleName = ref<string>('모달제목')
const popup: IModalPopup = reactive({
modalShow: {
show: false,
},
modalShowFooter: {
show: false,
},
})
const openModal = (modal: string) => {
popup[modal].show = true
}
// 여기있는 함수를 이용해서, 자식에서 보낸 emit을 받는다.
const handleCancel = (modal: string) => {
popup[modal].show = false
}
const handleConfirm = (modal: string) => {
popup[modal].show = false
}
</script>
<template>
<div>
<!-- 기본 모달(Footer가 없을 때) -->
<p>
기본 모달
<el-button @click="openModal('modalShow')">
모달 클릭
</el-button>
</p>
<Modal v-model="popup.modalShow.show" :title="titleName" :size="MODAL_SIZE.LARGE" @confirm="handleConfirm('modalShow')" @cancel="handleCancel('modalShow')">
// @cancel = 자식에서 emit으로 보낸 함수
// handleCancel = 자식에서 emit으로 보낸 함수를 실행하는 함수
// ('modalShow') = 인자값으러 넘기기
<template #content>
<p>모달 내용</p>
</template>
</Modal>
<!-- Footer가 있는 모달 -->
<p>
Footer가 있는 모달
<el-button @click="openModal('modalShowFooter')">
모달 클릭
</el-button>
</p>
<Modal v-model="popup.modalShowFooter.show" :title="titleName" :close-on-click-modal="false">
<template #content>
<p>모달 내용 </p>
</template>
<template #footer>
<button class="btn__primary-line btn--lg" @click="handleCancel('modalShowFooter')">
취소(Footer)
</button>
<button class="btn__search" @click="handleConfirm('modalShowFooter')">
확인(Footer)
</button>
</template>
</Modal>
</div>
</template>
<style scoped></style>