
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<transition name="fade">
<div v-if="visible" class="alert-wrap" role="dialog" aria-modal="true">
<div class="alert-box">
<div class="alert-header layout flex-end">
<button class="close-btn" @click="handleClose" aria-label="닫기">×</button>
</div>
<div class="alert-content">
<div class="primary-box">
<p class="alert-message">
<span class="icon" v-if="iconIsImage">
<img :src="icon" alt="" />
</span>
<span class="text" v-html="message" />
</p>
</div>
<p class="sub-message" v-if="subMessage">
<span class="sub-icon"><img src="../../../resources//img/component/common/ico_invalid_error_20.svg" alt="" /></span> {{ subMessage }}
</p>
</div>
<div class="alert-footer">
<button
v-if="isConfirm"
class="confirm-btn gray"
ref="cancelBtn"
@click="handleCancel"
>취소</button>
<button
class="confirm-btn black"
ref="confirmBtn"
@click="handleConfirm"
>확인</button>
</div>
</div>
</div>
</transition>
</template>
<script>
export default {
name: 'GlobalModal',
data() {
return {
visible: false,
isConfirm: false,
message: '', // 주 메시지
subMessage: '', // 하단 서브 메시지 (선택)
icon: '', // 이모지 or 아이콘 코드 (선택)
resolver: null,
};
},
created() {},
methods: {
showAlert({ message, icon = '', subMessage = '' }) {
this.message = message;
this.icon = icon;
this.subMessage = subMessage;
this.isConfirm = false;
this.visible = true;
return new Promise(resolve => {
this.resolver = resolve;
this.$nextTick(() => this.$refs.confirmBtn?.focus());
});
},
showConfirm({ message, icon = '', subMessage = '' }) {
this.message = message;
this.icon = icon;
this.subMessage = subMessage;
this.isConfirm = true;
this.visible = true;
return new Promise(resolve => {
this.resolver = resolve;
this.$nextTick(() => this.$refs.confirmBtn?.focus());
});
},
handleConfirm() {
this.visible = false;
this.resolver?.(true);
},
handleCancel() {
this.visible = false;
this.resolver?.(false);
},
handleClose() {
this.visible = false;
this.resolver?.(this.isConfirm ? false : true);
}
},
watch: {},
computed: {
iconIsImage() {
return typeof this.icon === 'string' && (this.icon.includes('.svg') || this.icon.includes('.png') || this.icon.startsWith('http'));
}
},
components: {},
mounted() {},
beforeUnmount() {},
};
</script>