-
[ Vue ] VCalendar 단일(single), 기간(range), 다중(multi), date-picker 구현Front/Vue 2025. 8. 5. 01:20반응형
date-picker를 찾다보면 대부분의 date-picker가 dropdown형식으로 되어서 vcalendar로 달력으로 바로 날짜를 선택할 수 있도록 기능을 구현
VCalendar를 사용하면서 css 작업이 생각보다 다른 라이브러리보다 좀 건드리기가 복잡했기에
혹시 css설정 관련해서 필요한것이 있으면 알려드리겠습니다.
Installment
vcalendar docs를 보며 진행
https://vcalendar.io/getting-started/installation.html
vcalendar를 사용하기 위해 라이브러리를 설치
npm install v-calendar@next @popperjs/core
전역으로 VCalendar를 전역으로 사용하기위해 main에서 전역으로 VCalendar 플러그인을 등록
import { setupCalendar, Calendar, DatePicker } from 'v-calendar'; import 'v-calendar/style.css'; // Use plugin defaults (optional) app.use(setupCalendar, {}) // Use the components app.component('VCalendar', Calendar) app.component('VDatePicker', DatePicker)
Single
calendar에서 단일 날짜 선택 기능을 구현
단일은 VDatePicker를 이용하고 v-model로 바인딩해주면 간단하게 구현이 가능하다
<script> const selectedDate = ref(null) </script> <template> <VDatePicker v-model="selectedDate" mode="date" /> </template>
Range
기간 선택의 경우에는 변수를 start와 end 객체로 초기화해준후
v-model로 바인딩해주고 is-range속성을 추가하면 기간선택이 date-picker가 된다.
<script> const rangeDate = ref({ start: null, end: null }) </script> <template> <VDatePicker v-model="rangeDate" is-range mode="date"/> </template>
Multi
multi의 경우에는 좀 다르게 기능을 구현해야한다
VDatePicker를 사용하여 v-model로 바인딩을 하면 단일만 선택되어서 docs에서 본 attributes를 이용해서 기능을 구현
attributes에 highlight: true 를 주고 dates리스트를 props로 전달해주면 리스트안에 있는 날짜가 선택되는 구조이므로,
이를 이용해서 multi 선택 기능을 구현
@dayclick은 선택한 날짜가 return되는데 이때 day.date에 날짜 값이 존재하여 이 값을 리스트에 담아줘야한다.
그래서 리스트에 값의 존재 여부를 파악하고 값을 추가하고 삭제하는 로직을 추가
<script> const multiDate = ref([ { highlight: true, dates: [] as Date[], }, ]) const toggleDateSelect = (day: any) => { const index = multiDate.value[0].dates.indexOf(day.date) if(index === -1) { multiDate.value[0].dates.push(day.date) return } multiDate.value[0].dates.splice(index,1) } </script> <template> <VDatePicker :attributes="multiDate" @dayclick="toggleDateSelect" /> </template>
Date Picker Popup
VDatePicker를 활용해서 datepicker 구현
open값을 보내서 VCalendar popup을 열고 닫고 구현,
date날짜를 바인딩하여 처리
popupRef를 활용하여 해당 컴포넌트 외부 클릭시 팝업을 닫히도록 설정
const showStartDate = ref(false) const repeatOption = reactive({ startDate: Date.now(), endDate: '', })
<select-date v-model="repeatOption.startDate" @click="showStartDate = !showStartDate"/> <app-calendar v-model="repeatOption.startDate" :open="showStartDate"/>
<script setup lang="ts"> import {onBeforeUnmount, onMounted, ref} from "vue"; const open = defineModel('open', {default: false}) const currentDate = defineModel() const popupRef = ref() const handleClickOutside = (event: MouseEvent) => { if (popupRef.value && !popupRef.value.contains(event.target as Node)) { open.value = false } } onMounted(() => { document.addEventListener('mousedown', handleClickOutside) }) onBeforeUnmount(() => { document.removeEventListener('mousedown', handleClickOutside) }) </script> <template> <div v-if="open" ref="popupRef" class="calendar-popup-wrapper"> <VDatePicker v-model="currentDate" mode="date"/> </div> </template>
728x90반응형'Front > Vue' 카테고리의 다른 글
[ Vue ] Index DB 용량 가져오기 (1) 2025.07.29 [ Vue ] Vue Draggable (0) 2025.07.15 [ Vue ] vue-i18n 다국어 기능 (2) 2025.07.11 [ Vue ] Pinia Store 이용하기 ( 전역으로 팝업 관리 ) (1) 2025.07.11 [ Vue ] FullCalendar 반응형 주입 (1) 2025.07.08