ABOUT ME

-

  • [ Vue ] FullCalendar 반응형 주입
    Front/Vue 2025. 7. 8. 00:18
    반응형

    FullCalendar를 사용하다보면 부모의 크기가 변경이 되는 상황에서는 FullCalendar의 크기는 resize가 되지 않아서 부모의 크기에 맞춰서 자동으로 FullCalendar도 크기 조절이 되도록 반응형으로 만들어줘야한다.


    Installment

    우선 FullCalendar를 사용하기해 라이브러리를 설치 우선 daygrid만 설치해서 테스트를 진행

    npm install @fullcalendar/vue3 @fullcalendar/core @fullcalendar/daygrid

    initial setup

    일단 초기 테스트를 위해 fullcalendar 기본 데이터를 넣고 렌더링 

    <script setup lang="ts">
    import FullCalendar from '@fullcalendar/vue3'
    import dayGridPlugin from '@fullcalendar/daygrid'
    import {nextTick, onBeforeUnmount, onMounted, ref} from "vue";
    
    const calendarOptions = {
      plugins: [dayGridPlugin],
      initialView: 'dayGridMonth',
      events: [
        { title: '회의', date: '2025-07-01' },
        { title: '출장', date: '2025-07-04' },
      ],
    }
    </script>
    
    <template>
      <div class="panel-calendar-wrapper">
        <FullCalendar
            :options="calendarOptions"
        />
      </div>
    </template>
    
    <style scoped lang="scss">
    .panel-calendar-wrapper {
      width: 100%;
      height: 100%;
    }
    </style>

     

    이러면 일단 fullCalendar가 화면에 렌더링 되는것을 볼 수 있다. 아이콘이나 ui/ux는 나중에 css로 작업하면 되기에 무시

    현재 부모 영역은 split으로 width값의 크기를 조절할 수 있게 했는데 부모의 영역의 크기를 조절하면 FullCalendar의 ui/ux가 깨지는 것을 볼 수 있다.

    이를 해결하기 위해 fullcalendar에 반응형을 주입

     


    Responsive DOM Binding

    fullcalendar의 width값은 부모의 크기가 변하면 자동으로 fullcalendar의 width는 변하게 된다.

    하지만 이때 fullcalendar의 ui/ux는 해당 width에 따라서 자동으로 캘린더의 모양이 변하지 않으므로 크기가 변할때마다 캘린더의 크기를 다시 조정해줘야한다.

     

    따라서 calendar의 크기의 변경을 감지할 수 있도록 observer를 설정 관찰하는 것은 FullCalendar의 element요소

    getApi().updateSize()를 호출하면 캘린더가 다시 그려지므로 observer에서 변경이되면

    updateSize를 호출하여 캘린더를 다시 그려준다.

     

    마지막으로 observer 메모리 누수를 방지하기위해 해당 캘린더 컴포넌트가 unmount되는 시점에 observer를 다시 지워준다.

    <script setup lang="ts">
    import FullCalendar from '@fullcalendar/vue3'
    import dayGridPlugin from '@fullcalendar/daygrid'
    import {nextTick, onBeforeUnmount, onMounted, ref} from "vue";
    
    const calendarLocalRef = ref()
    const resizeObserver = ref()
    
    const calendarOptions = {
      plugins: [dayGridPlugin],
      initialView: 'dayGridMonth',
      events: [
        { title: '회의', date: '2025-07-01' },
        { title: '출장', date: '2025-07-04' },
      ],
    }
    
    onMounted(() => {
      nextTick(() => {
        const el = calendarLocalRef.value?.$el
        if (!el) return
    
        resizeObserver.value = new ResizeObserver(() => {
          calendarLocalRef.value?.getApi()?.updateSize()
        })
    
        resizeObserver.value.observe(el)
      })
    })
    
    onBeforeUnmount(() => {
      resizeObserver.value.disconnect()
    })
    </script>
    
    <template>
      <div class="panel-calendar-wrapper">
        <FullCalendar
            ref="calendarLocalRef"
            :options="calendarOptions"
        />
      </div>
    </template>
    
    <style scoped lang="scss">
    .panel-calendar-wrapper {
      width: 100%;
      height: 100%;
    }
    </style>

     

    이러면 부모의 크기가 변함에 따라 캘린더도 정상적으로 변하는 것을 확인할 수 있다.

     

    728x90
    반응형