728x90
진행중인 프로젝트에서 이벤트를 진행하게 되어 팝업을 띄워달라는 요청사항을 전달 받았다.
팝업은 브라우저 자체에서 팝업보지 않기를 진행하면 해당 팝업이 뜨지않기 때문에 모달로 진행을 했다.
모달은 브라우저 설정과 관계없이 띄울 수 있기에 팝업기능을 대신하여 모달로 띄우는 추세라고한다.
모달은 Element ui의 dialog를 사용했다.
페이지를 들어올 때마다 모달을 띄우고 싶었기 때문에
모든 페이지에서 공통적으로 사용하고 있는 footer 컴포넌트에 해당 모달을 구현하였다
전체적인 플로우
- 쿠키를 사용하여 전달해야하는 데이터가 아니기 때문에 클라이언트 상에서 해결
세션 종료 후에도 유지되어야하므로 로컬스토리지에서 진행
- 최초 모달 오픈 페이지 들어오면 모달 오픈 → 새로고침 시에도 모달 오픈
- 다시 보지 않기 → 이후로 모달 오픈 안함
- 로컬스토리지에 모달 오픈 플래그 설정하여 관리
- boolean 값으로 설정
- 모달 오픈시( footer 가 마운트 되기 전 )에 해당 로컬스토리지 값 확인하여 오픈여부 결정
- 오늘 다시 보지 않기 → 자정을 이후로 다시 모달 오픈
- 로컬스토리지에 모달 오픈 플래그 설정하여 관리
- 유효기간을 설정하여 로컬 스토리지에 저장
- 모달 오픈시( footer 가 마운트 되기 전 )에 로컬스토리지 값을 현재 시간과 비교하여 오픈 여부 결정
자세한 사항은 코드 주석처리
<template>
<div class="footer">
...
</div>
<el-dialog
v-model="isOpen"
append-to-body
:fullscreen="true"
class="event-dialog"
>
<template #header="{ close, titleId, titleClass }">
<ul class="my-header">
<li>
<input type="checkbox" id="oneDay" :value="showOneDay" @click="clickOneDay" >
<label for="oneDay"><i class="uil uil-check"></i></label>
<span><label for="oneDay">오늘 하루 보지않기</label></span>
</li>
<li>
<input type="checkbox" id="never" :value="showNever" @click="clickNever" >
<label for="never"><i class="uil uil-check"></i></label>
<span><label for="never">다시 보지 않기</label></span>
</li>
</ul>
</template>
<EventGJPlus/>
</el-dialog>
</template>
<script setup lang="ts">
import {ElDialog} from 'element-plus'
const isOpen = ref(true)
const showOneDay = ref(false)
const showNever = ref(false)
onBeforeMount(() => {
let date = new Date()
//모달 종료 날짜
let endDate : Date | number= new Date(2022, 11, 30, 23, 59, 59)
endDate = endDate.setTime(endDate.getTime())
const now = date.setTime(date.getTime())
//종료 시점보다 현재시간이 크기때문에 모달 띄우지 않음
//해당 모달 종료 시점이 지났으므로 해당 로컬 스토리지값 제거
if(now > endDate ){
isOpen.value = false;
localStorage.removeItem('EVENT_POPUP_ONE')
localStorage.removeItem('EVENT_POPUP_NEVER')
return
}
// 유효 기간 더 크면 팝업 안보이게
// 다시 안보기인 경우 팝업 안보이게
if((parseInt(localStorage.getItem('EVENT_POPUP_ONE') ) > now)
|| Boolean(localStorage.getItem('GJ_POPUP_NEVER'))){
isOpen.value = false
}
})
function clickOneDay(e:Event){
const isChecked = (e.target as HTMLInputElement).checked
if(isChecked){
const date = new Date()
//다음날 00:00:00 까지
const expiredTime = new Date(2022, 10, date.getDate() + 1, 0, 0, 0).getTime()
localStorage.setItem('EVENT_POPUP_ONE', expiredTime +'')
isOpen.value = false; //모달 닫기
}
}
function clickNever(e:Event){
const isChecked = (e.target as HTMLInputElement).checked
if(isChecked){
localStorage.setItem('EVENT_POPUP_NEVER', 'true')
isOpen.value = false;
}
}
</script>
<style lang="scss">
.my-header{
display: inline-flex;
li{
&:not(:last-child){
margin-right: 10px;
}
input[type='checkbox'] + label{
color: red;
}
}
}
</style>
728x90
반응형