본문 바로가기
Frontend/Nuxt.js

Nuxt.js - 모달을 사용하여 오늘하루보지않기(Element ui)

by Hyeonlog 2022. 11. 15.
728x90

진행중인 프로젝트에서 이벤트를 진행하게 되어 팝업을 띄워달라는 요청사항을 전달 받았다.

 

팝업은 브라우저 자체에서 팝업보지 않기를 진행하면 해당 팝업이 뜨지않기 때문에 모달로 진행을 했다.

모달은 브라우저 설정과 관계없이 띄울 수 있기에 팝업기능을 대신하여 모달로 띄우는 추세라고한다.

 

모달은 Element ui의 dialog를 사용했다.

 

페이지를 들어올 때마다 모달을 띄우고 싶었기 때문에

모든 페이지에서 공통적으로 사용하고 있는 footer 컴포넌트에 해당 모달을 구현하였다

 

전체적인 플로우

- 쿠키를 사용하여 전달해야하는 데이터가 아니기 때문에 클라이언트 상에서 해결

세션 종료 후에도 유지되어야하므로 로컬스토리지에서 진행

  1. 최초 모달 오픈 페이지 들어오면 모달 오픈 → 새로고침 시에도 모달 오픈
  2. 다시 보지 않기 → 이후로 모달 오픈 안함
    1. 로컬스토리지에 모달 오픈 플래그 설정하여 관리
    2. boolean 값으로 설정
    3. 모달 오픈시( footer 가 마운트 되기 전 )에 해당 로컬스토리지 값 확인하여 오픈여부 결정
  3. 오늘 다시 보지 않기 → 자정을 이후로 다시 모달 오픈
    1. 로컬스토리지에 모달 오픈 플래그 설정하여 관리
    2. 유효기간을 설정하여 로컬 스토리지에 저장
    3. 모달 오픈시( 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
반응형