vue-awesome-swiper loop 옵션 적용시 버그 우회 방법

Nekoromancer·2021년 5월 25일
1

찾아보니 vue-awesome-swiper에 Loop 옵션을 적용할 경우 발생하는 버그 때문에 고통받는 사람이 많았고, 나도 고통 받았기 때문에 기록을 겸해 끄적여 본다.

참고로 어디까지나 정상적으로 동작하는 것처럼 보이게 하도록 우회하는 것일뿐 근본적인 해결은 아닐 뿐이니, 이 점은 참고 바란다.

1. 초기화 지연

loop 옵션에서 발생하는 문제들의 대부분은 v-for 로 slide 요소들을 생성하는데서 발생한다. swiper의 init 옵션을 false로 한후, slide 요소들이 완전히 파싱된 후 swiper를 초기화 시킨다.

  <swiper
      ref="mySwiper"
      :options="options"
  >
    // dataset 으로부터 slide를 v-for로 반복을 돌려 slide를 파싱한다
    <swiper-slide v-for="item in dataset">...</swiper-slide>
  </swiper>
//...//
<script>
  //...//
  const state = reactive({
    mySwiper: null,
    options: {
      init: false,
      loop: true,
    },
    dataset: [],
  });
  
  const getData = () => {
    $axios.get(...)
      .then(({ data }) => {
      	 state.dataset = data;
         nextTick(() => {
           // 이 시점에서 스와이퍼를 init 한다
           state.mySwiper.$swiper.init();
         });
      });
  };

2. 슬라이드가 1장인 경우

데이터를 내려받았는데 슬라이드가 1장인 경우 Loop 옵션이 적용되면 기묘한 동작을 하는 경우가 있다. 대표적으로 이미지에 Lazyload 작업을 한 경우 슬라이드를 할때마다 매번 로딩이 도는 상황을 경험할 수 있다.

그럼 Loop 옵션을 데이터 길이에 따라서 유동적으로 줄 수 있지 않을까? 했지만 데이터가 변경된다고 해도, 이후에 바뀐 Loop 옵션이 스와이퍼에 적용되지 않았다. 이 경우 init을 하기전에 아예 v-if를 통해 loop을 true/false 여부가 판명날때까지 DOM 자체를 출현시켜버리지 않으면 된다.

  <swiper
      v-if="dataset.length > 0"
      ref="mySwiper"
      :options="options"
  >

3. onSlideChange Event

3-1. 현재 Index 는?

loop 옵션이 false일 경우 event에 activeIndex로 알 수 있지만, loop 옵션이 true인 경우 activeIndex는 Loop 구현을 위해 중복 생성된 슬라이드의 Index 번호를 반환한다.

따라서 activeIndex 가 아니라 realIndex 를 참조하면 된다.

3-2. Autoplay 적용시

Autoplay 적용시 onSlideChange Event가 완전히 한바퀴 돈 다음 0번 Index 에서 1번 Index로 바뀔 때 realIndex 0번의 이벤트가 발생한 후 곧바로 1번이 발생한다. Log를 찍어보면, 0, 0, 1이 찍히는 것을 알 수 있다. 혹시 onSlideChange에 뭔가 작업을 걸고 있다면 debounce 함수를 적용한다면 해결 할 수 있다.

onSlideChange: debounce(({ realIndex }) => {
  actions.doSomething(realIndex);
}, 300),
profile
고양이 앓이 중인 프론트엔드 개발자

0개의 댓글