FrontEnd/Vue.js

vue.js 에서 resize 감지 하는 방법 && carousel 스크린 사이즈 별 데이터 표시하기

김평범님 2023. 4. 4. 20:13
반응형

UI상 한 화면에 많은 데이터를 이용할 때 carousel을 이용해 준다.

vue carousel 라이브러리를 확인해 보면 가로, 세로 몇 개씩 콘텐츠를 보여줄지 변수로 지정을 하는데

이때 화면 크기에 따라서 자동으로 수정되는 UI를 만들어보도록 하겠다.

 


 

💛Vue Carousel 라이브러리 추천

https://www.npmjs.com/package/vue-slick-carousel

 

vue-slick-carousel

Vue Slick Carousel with True SSR Written for Faster Luxstay. Latest version: 1.0.6, last published: 3 years ago. Start using vue-slick-carousel in your project by running `npm i vue-slick-carousel`. There are 38 other projects in the npm registry using vue

www.npmjs.com

현재 내가 이용하고 있는 vue-slick-carousel 가로 세로 보여줄 카드 크기를 결정할 수 있고,

예시페이지도 매우 제공이 잘되어있다.👍

 

 

 

✅vue-slick-carousel 연결하기

npm install vue-slick-carousel 

npm 명령어로 바로 설치가 가능하다.

 

 

 

👨‍🦰간단한 샘플 예시코드

example.vue

<template>
    <div style="padding:40px; background:gray;">
        <VueSlickCarousel
                :rows="2"
                :slidesToShow="2">
            <div v-for="i in 10" class="pd16">
                <div class="card">{{i}}</div>
            </div>
        </VueSlickCarousel>
    </div>
</template>
<script>
    import VueSlickCarousel from 'vue-slick-carousel';
    import 'vue-slick-carousel/dist/vue-slick-carousel.css';
    import 'vue-slick-carousel/dist/vue-slick-carousel-theme.css';


    export default {
        components: {
            VueSlickCarousel
        },
    };
</script>
<style>
    .pd16 {
        padding: 16px;
    }

    .card {
        height: 250px;
        background: pink;
        border-radius: 8px;
        color: #fff;
        text-align: center;
    }
</style>

 설치가 완료되었으면 important로 라이브러리를 가져와준 뒤 실행시킬 수 있다.

지금은 10개의 카드가 보이는 단순한 캐러셀을 만들어 주었다.

 

결과화면

carousel만들어진 화면

 

적용한 속성을 보면 :row와 :slideToShow를 넣어주었다.

  • :rows : 세로로 보여줄 카드 수
  • :slideToShow: 가로로 보여줄 카드 수

(옵션 별 자세한 사항은 위 npm 사이트 참고해 보자😎)

 

위의 형태로 하면 한화면에 가로2개 세로2개로

한번에 총 4개의 카드가 보이게 된다.

 

 

좀 더 고민을 해보면 이렇게 보이는 slide의 개수를 화면상 크기에 맞춰서  가변적으로 바꿀 수 없을까?🙄

고민하게 된다.

그래서 아래 코드를 추가하게 되었다.

 


👧Vue.js resize 시 화면 크기 계산하기

javascript에서 제공하는 이벤트 리스너를 이용하면 이벤트 처리가 가능해진다.

 

 

 

아직 이벤트 리스너 기능을 잘 모른다면? 아래 포스팅 참고하기!

https://ordinary-code.tistory.com/64

 

[JavaScript] 이벤트리스너(Event Listener)란? - 사용법 및 주의사항

동적인 웹 애플리케이션의 구현을 위해서는 사용자의 다양한 이벤트에 맞춰 데이터를 핸들링해야 된다. 이러한 개념에서 Javascript 이벤트 객체에 대해서 관심을 가질 필요가 있다. 🎉 JavaScirpt

ordinary-code.tistory.com

 

 

 

그래서 나온 코드는 아래와 같다.

example.vue

<template>
    <div style="padding:40px; background:gray;">
        <!-- carousel row, col 변수로 연결,
        css를 이용해서 .card 클래스에 높이250 지정-->
        <VueSlickCarousel
                :arrow="true"
                :slidesToShow="carouselParam.col"
                :rows="carouselParam.row"
        >
            <div v-for="i in 100" :key="i" class="pd16">
                <div class="card">
                    {{i}}
                </div>
            </div>
        </VueSlickCarousel>
    </div>
</template>
<script>
    import VueSlickCarousel from 'vue-slick-carousel';
    import 'vue-slick-carousel/dist/vue-slick-carousel.css';
    import 'vue-slick-carousel/dist/vue-slick-carousel-theme.css';


    export default {
        components: {
            VueSlickCarousel
        },
        data() {
            return {
                carouselParam: {
                    row: 6,
                    col: 4,
                },
            };
        },
        mounted() {
        	//페이지 접속 시 resize 이벤트 핸들러 추가
            window.addEventListener('resize', this.handleResize);
            //최초 한번 실행
            this.handleResize();
        },
        beforeDestroy() {
        	//페이지 떠날 때 이벤트 핸들러 삭제
            window.removeEventListener('resize', this.handleResize);
        },
        methods: {
            handleResize() {
                const vm = this;
                //resize 실행마다 width, height 가져오기
                let width = window.innerWidth;
                let height = window.innerHeight;
                
                //브라우저 넓이에 따라서 보여질 카드 개수 표시
                if (width < 768) {
                    vm.carouselParam.col = 1;
                } else if (width >= 768 && width < 970) {
                    vm.carouselParam.col = 2;
                } else if (width >= 970 && width < 1400) {
                    vm.carouselParam.col = 3;
                } else if (width >= 1400 && width < 1800) {
                    vm.carouselParam.col = 4;
                } else if (width >= 1800) {
                    vm.carouselParam.col = 5;
                }
                
                //높이에 딱 채울 카드 개수 계산하기
                //padding값까지 포함한 282px을 높이로 나눠줘서
                //최대 들어갈 수 있는 카드 개수 정하기
                let row = Math.floor(height / 282);
                
                //라이브러리 특성한 row 개수가 우선시 됨
                let maxCol = Math.ceil(100 / vm.carouselParam.col);
                vm.carouselParam.row = maxCol < row ? maxCol : row;
            },
        },
    };
</script>
<style>
    .pd16 {
        padding: 16px;
    }

    .card {
        height: 250px;
        background: pink;
        border-radius: 8px;
        color: #fff;
        text-align: center;
    }
</style>

 

1️⃣이벤트 리스너 추가/삭제 코드 넣어주기

mounted()로 해당 페이지에 접근할 때 먼저 이벤트 리스너를 추가해 주고, 실행시켜 준다.

페이지 누수 방지를 위해서 beforedestory()로 페이지에서 나갈 때 이벤트 리스너를 꼭 삭제해 주자.

 

 

2️⃣resize 될 때마다 실행될 function 코드 넣어주기

handleResize function에서는 페이지 크기가 변경될 때마다

브라우저의 width와 height값을 가져온다

 

해당 조건에 맞춰서 보여줄 행, 열 값을 결정해 준다.

 

width 조건의 경우 넓이가 좁아질수록, 보여주는 행 카드 수를 줄여주는 코드를 넣어줬고

 

height 조건의 경우 지금 브라우저 높이에서 card height를 나눠서

한 페이지에 총 몇 개의 카드가 들어가는지를 체크해 주었다.

:row 조건에는 정수만 받을 수 있기 때문에 Math.floor()를 이용해서 내림을 해주었다.

 

 

결과화면

페이지 넓이 조정마다 알아서 카드 개수를 조절해주게된다.

 

 

💙vue-slick-carousel 특성 보정하기 

만약 캐러셀이 동작할 만큼 카드가 없는 경우

Vue-slick-carousel에서는 row개수를 우선해서 카드를 정렬하게 된다. for문이 100개가 아니라 15개로 줄여보겠다.

 

row개수가 우선시 되어서 한쪽이 비어보이는 캐러셀이 나오게됨

maxCol로 보정이 필요한 이유는 만약 15개로 for문을 줄여보았다.

 

 

화면상 한 페이지에 모든 데이터가 표시가 가능한 상황이 되면

가로를 우선 채워주지 않고 세로로 우선 콘텐츠를 채워져서 한쪽이 비어 보이게 된다.

이래서 총 개수 세로 값보다 row 세로값이 큰 경우는 maxCol을 우선 적용해 준다.

 

maxCol 보정 코드를 추가한 결과화면

이런 식으로 maxCol값으로 보정을 하면 한쪽이 비어보이는 캐러셀이 아닌

꽉 찬 캐러셀을 만들 수 있다.

 

 

 

반응형