vue.js/vue.js 라이브러리

[vue.js] vue2-datepicker 캘린더 주(week) 단위 선택 및 style 설정하기

반응형

서론

프로젝트에서 캘린더를 주(week)단위로 선택 해야하는 기능 요청이 있어서 적용하게 되었다.

 

설치

캘린더 라이브러리는 많지만 vue2-datepicker 라이브러리를 사용했다.

npm i vue2-datepicker

소스

<template>
  <div class="container">
    선택한 주 : {{ dateRange.start }} ~ {{ dateRange.end }}
    <br />
    <br />
    <date-picker
      inline
      :editable="false"
      valueType="format"
      format="YYYYMMDD"
      :getClasses="getClasses"
      :lang="datepickerLang"
      :value="weekTime"
      :disabled-date="dislabedDate"
      @pick="calendarPick"
    />
  </div>
</template>

<script>
import DatePicker from "vue2-datepicker";
import "vue2-datepicker/index.css";
import moment from "moment";

export default {
  components: { DatePicker },
  data() {
    return {
      weekTime: null,
      dateRange: {
        start: null,
        end: null,
      },
      datepickerLang: {
        yearFormat: "YYYY년",
        monthFormat: "M월",
        monthBeforeYear: false,
      },
    };
  },
  methods: {
    // 선택한 영역 class set
    getClasses(cellDate, currentDates) {
      if (currentDates.length === 0) return;
      //기준 날짜
      const cellDateVal = moment(cellDate).format("YYYYMMDD");
      // 주 시작일 날짜
      const startWeekDay = moment(currentDates[0])
        .startOf("week")
        .format("YYYYMMDD");
      // 주 종료일 날짜
      const endWeekDay = moment(currentDates[0])
        .endOf("week")
        .format("YYYYMMDD");
      
      // 주 시작점 & 종료점 class
      if (cellDateVal === startWeekDay || cellDateVal === endWeekDay) {
        return "active";
      }
      // 중간영역 class
      if (
        moment(cellDateVal).isAfter(startWeekDay) &&
        moment(cellDateVal).isBefore(endWeekDay)
      ) {
        return "in-range";
      }
    },
    // 캘린더 비활성화 영역 - 당일 주를 포함하여 선택 가능
    dislabedDate(date) {
      return (
        moment(date).format("YYYYMMDD") >=
        moment()
          .add("7", "days")
          .startOf("week")
          .format("YYYYMMDD")
      );
    },
    calendarPick(item) {
      this.weekTime = moment(item).format("YYYYMMDD");
      // 선택한 날짜의 주 첫째일과 마지막일 date set - 첫째일을 일요일로 설정
      this.dateRange.start = moment(item)
        .startOf("week")
        .format("YYYYMMDD");
      this.dateRange.end = moment(item)
        .endOf("week")
        .format("YYYYMMDD");
    },
  },
};
</script>

설명

data

weekTime : datepicker에서 주고받을 데이터

dateRange : 주 단위 시작 / 종료 날짜 데이터

datepickerLang : 캘린더에서 사용할 lang

ex)

datepickerLang: {
        yearFormat: "YYYY년",
        monthFormat: "M월",

}

method

getClasses : 선택한 영역에 class를 적용하기 위한 메소드로 현재 캘린더의 일자별로 for를 돌면서 해당 메소드를 호출한다. 여기서 cellDate 는 4월25일 ~6월5일까지의 날짜가 전달되고 currentDates는 현재 선택한 데이터 즉 weekTime 데이터가 넘어온다.

* 메소드 안에 currentDates[0] 로 되어있는 이유는 해당 라이브러리 데이터가 range도 포함하여 시작 ~ 종료 데이터도 set할수 있으므로 배열로 넘어온다.

시작 / 종료일자는 moment 를 사용하여 가져온다.

ex)

const startWeekDay = moment(currentDates[0]).startOf("week").format("YYYYMMDD");
const endWeekDay = moment(currentDates[0]).endOf("week").format("YYYYMMDD");

vue2-datepicker에서 제공하는 css에서 선택한 영역은 active로 range 중간 영역은 in-range 로 class를 선언하고 있으므로 시작 / 종료일자는 active, 그 중간 영역은 in-range class를 주기위해 return 한다.

 

dislabedDate : 캘린더 비활성화 영역을 set 하는 메소드로 getClasses과 동일하게 현재 캘린더의 일자별로 호출한다. 여기서 사용한 date가 getClasses의 cellDate과 동일하다. false를 return 하면 선택가능하고 true를 return하면 disabled 일자가 적용된다.

 

calendarPick : 캘린더에서 선택시 호출하는 메소드로 선택한 데이터를 기반으로 주 시작일 / 종료일을 set한다.

확인

* 테스트 소스 : https://github.com/hjh830827/test-project1

DatepickerTest.vue에서 확인 가능합니다.

반응형