결과 화면

 

버전

vue: 2.7.10

nuxt: 2.15.8

 

vue, nuxt 버전 2.x.x 기준으로 작성한 글이기 때문에 버전  3.x.x에서는 동작하지 않을 수 있다.

 

2023.11 기준 스와이퍼 버전 11까지 나왔다.

최신 버전의 뷰 스와이퍼에 대한 자세한 설명은 공식 문서를 참고한다.

https://swiperjs.com/vue

 

1. swiper, vue-awesome-swiper 패키기 설치하기

swiper와 vue-awesome-swiper 패키지를 설치한다.

반드시 해당 버전으로 설치한다.

yarn add swiper@5.4.5
yarn add vue-awesome-swiper@4.1.1

또는

npm install swiper@5.4.5
npm install vue-awesome-swiper@4.1.1

 

 

2. 마크업 하기

  • pages/swiper.vue
  1. 컴포넌트가 아닌 HTML로 마크업 한다. 이때 class명은 swiper 패키지에서 제공하는 것으로 사용한다.
    (swiper-container, swiper-wrapper, swiper-slide)
  2. 커스텀으로 autoplay, progress를 만들 것이기 때문에 마찬가지로 HTML로 마크업 한다.
    autoplay 속성의 true/false에 따라서 css가 바뀌어야 하기 때문에 클릭 이벤트와 :class 속성을 추가한다.
<template>
  <section class="kv-swiper">
    <div
      v-once
      v-swiper:swiper="kvSwiperOption"
      class="swiper-container">
      <ul class="swiper-wrapper">
        <li class="swiper-slide">Slide 1</li>
        <li class="swiper-slide">Slide 2</li>
        <li class="swiper-slide">Slide 3</li>
      </ul>
    </div>

    <div class="swiper-function">
      <div
        class="swiper-autoplay"
        :class="{ stop: kvAutoplay }"
        @click="kvSwiperAutoplay">
        <span/>
      </div>

      <div
        class="swiper-progress"
        :class="{ start: kvProgress }">
        <span class="bar"/>
      </div>

      <div class="swiper-pagination"/>
    </div>
  </section>
</template>

 

3. script 작성하기

  1. v-once, v-swiper 디렉티브를 사용하기 위해서 vue 컴포넌트를 import 한다.
  2. vue-awesome-swiper와 swiper.css를 import 한다.
  3. kvAutoplay, kvProgress를 false로 설정한다. (페이지가 로딩되기 전에 동작되면 안 되기 때문에)
  4. kvSwiperOption을 작성한다. kvSwiperOption의 on 부분에 autoplay에 관한 메서드를 작성한다.
    (다음 슬라이드로 넘길 때 autoplay와 progress를 초기화하기 위해서)
    스와이퍼의 다양한 속성들을 사용하고 싶으면 공식 문서를 참고한다. (https://swiperjs.com/demos
  5. autoplay와 progress 동작에 필요한 메서드를 작성한다. 이때 try/catch 구조로 작성해야 한다.
<script>
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/css/swiper.css'

Vue.use(VueAwesomeSwiper)

export default {
  name: 'SwiperPage',

  data() {
    return {
      // Kv autoplay, progress
      kvAutoplay: false,
      kvProgress: false,

      // Kv swiper option
      kvSwiperOption: {
        effect: 'fade',
        slidesPerView: 1,
        spaceBetween: 0,
        loop: true,
        autoplay: {
          delay: 5000
        },
        pagination: {
          el: '.swiper-pagination',
          type: 'fraction'
        },
        on: {
          init: this.init,
          sliderMove: this.stopAutoplay,
          slideChangeTransitionStart: this.stopAutoplay,
          transitionEnd: this.startAutoplay
        }
      }
    }
  },

  methods: {
    init() {
      this.kvProgress = true
    },

    kvSwiperAutoplay() {
      this.kvAutoplay = !this.kvAutoplay

      if (this.kvProgress) {
        this.stopAutoplay()
      } else {
        this.startAutoplay()
      }
    },

    stopAutoplay() {
      try {
        this.swiper.autoplay.stop()
        this.kvProgress = false
      } catch (err) {
        console.error(err)
      }
    },

    startAutoplay() {
      try {
        this.swiper.autoplay.start()
        this.kvProgress = true
        this.kvAutoplay = false
      } catch (err) {
        console.error(err)
      }
    }
  }
}
</script>

 

4. css/scss 작성하기

  1. progress는 script의 autoplay 속도와 css의 keyframes과 animation 속도에 맞춰 움직일 수 있도록 css를 작성한다. (animation: kvProgress 5s linear infinite;)
  2. 스와이퍼에 필요한 css를 작성한다.
<style lang="scss" scoped>
@keyframes kvProgress {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}

.kv-swiper {
  position: relative;
  height: 300px;
  padding: 20px;

  .swiper-container {
    height: 100%;

    .swiper-slide {
      ...
    }
  }

  .swiper-function {
    ...

    .swiper-autoplay {
      position: relative;
      cursor: pointer;

      span {
        &::after {
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          width: 4px;
          height: 12px;
          border-left: 2px solid #fff;
          border-right: 2px solid #fff;
          content: '';
        }
      }

      &.stop {
        span {
          &::after {
            width: 0;
            height: 0;
            border-right: 0;
            border-left: 10px solid #fff;
            border-top: 6px solid transparent;
            border-bottom: 6px solid transparent;
          }
        }
      }
    }

    .swiper-progress {
      overflow: hidden;
      width: 300px;
      height: 4px;
      background-color: rgba(255, 255, 255, 0.5);
      border-radius: 4px;

      &.start {
        .bar {
          animation: kvProgress 5s linear infinite;
        }
      }

      .bar {
        display: block;
        width: 100%;
        height: 4px;
        transform: translateX(-100%);
        background-color: #fff;
      }
    }

    .swiper-pagination {
      ...
    }
  }
}
</style>

결과 화면

 

버전

vue: 2.7.10

nuxt: 2.15.8

 

vue, nuxt 버전 2.x.x 기준으로 작성한 글이기 때문에 버전  3.x.x에서는 동작하지 않을 수 있다.

 

2023.11 기준 스와이퍼 버전 11까지 나왔다.

최신 버전의 뷰 스와이퍼에 대한 자세한 설명은 공식 문서를 참고한다.

https://swiperjs.com/vue

 

1. swiper, vue-awesome-swiper 패키기 설치하기

swiper와 vue-awesome-swiper 패키지를 설치한다.

반드시 해당 버전으로 설치한다.

yarn add swiper@5.4.5
yarn add vue-awesome-swiper@4.1.1

또는

npm install swiper@5.4.5
npm install vue-awesome-swiper@4.1.1

 

2. Swiper, SwiperSlide 컴포넌트 사용해서 마크업 하기

  • pages/swiper.vue
  1. 슬라이드 부분은 <Swiper>와 <SwiperSlide> 컴포넌트를 사용해서 마크업 한다.
  2. autoplay 버튼과 pagination 부분은 HTML로 마크업 한다.
  3. autoplay의 true/false에 따라 css가 달라져야 하기 때문에 :class 속성을 추가한다.
<template>
  <section class="kv-swiper">
    <Swiper
      :options="kvSwiperOptions"
      ref="kvSwiper">
      <SwiperSlide>Slide 1</SwiperSlide>
      <SwiperSlide>Slide 2</SwiperSlide>
      <SwiperSlide>Slide 3</SwiperSlide>
    </Swiper>

    <div class="kv-function">
      <div
        class="swiper-autoplay"
        :class="{ stop: kvAutoplay }"
        @click="kvSwiperAutoplay">
        <span/>
      </div>
      <div
        class="swiper-pagination"
        :class="{ stop: kvPagination }"
        slot="pagination"/>
    </div>
  </section>
</template>

 

3. script 작성하기

  1. Swiper, SwiperSlide 컴포넌트와 swiper.css 파일을 import 한다.
  2. 커스텀 페이지네이션을 만들기 위해서 kvSwiperOptions의 pagination 부분에 renderBullet 속성을 추가한다.
  3. renderBullet 부분에 <svg> 태그를 사용해서 기존 페이지네이션 태그 대신에 <svg> 태그가 대신 렌더링 되게 한다.
  4. autoplay와 pagination 동작에 필요한 메서드를 작성한다.
<script>
import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
import 'swiper/css/swiper.css'

export default {
  name: 'SwiperPage',

  components: {
    Swiper,
    SwiperSlide
  },

  data() {
    return {
      // kv autoplay, pagination
      kvAutoplay: false,
      kvPagination: false,

      // kv swiper options
      kvSwiperOptions: {
        effect: 'fade',
        slidesPerView: 1,
        spaceBetween: 0,
        loop: true,
        autoplay: {
            delay: 3800,
            disableOnInteraction: false
        },
        pagination: {
          el: '.swiper-pagination',
          clickable: true,
          paginationType: 'custom',
          renderBullet: function () {
            return `<div class="swiper-pagination-bullet">
              <svg viewBox="0 0 48 48" width="24" height="24" xml:space="preserve" id="svg">
                <circle class="pagination-loader" cx="24" cy="24" r="23" stroke="#da291c" fill="none" stroke-width="4" stroke-linecap="round"></circle>
                <circle class="pagination-circle" cx="24" cy="24" r="23" stroke="#fff" fill="none" stroke-width="4" stroke-linecap="round"></circle>
              </svg>
            </div>`
          }
        }
      }
    }
  },

  computed: {
    kvSwiper() {
      return this.$refs.kvSwiper.$swiper
    }
  },

  methods: {
    kvSwiperAutoplay() {
      this.kvAutoplay = !this.kvAutoplay
      this.kvPagination = !this.kvPagination

      if (this.kvAutoplay) {
        this.kvSwiper.autoplay.stop()
      } else {
        this.kvSwiper.autoplay.start()
      }
    }
  }
}
</script>

 

4. css/scss 작성하기

움직이는 svg 이미지를 만들기 위해서는 css가 매우 중요하다.

 

stroke-dasharray 속성은 선을 dash(점선) 형태로 만든다.

dasharray 값은 점선을 만드는 간격을 의미하고, 숫자가 작아질수록 점선이 촘촘하다.

 

stroke-dashoffset 속성은 svg 이미지가 어떤 지점부터 시작할지 정해준다.

시작점은 시계방향의 90도이다.

또한 dash 값들은 svg 태그의 path 값과 관련이 있어 글로 된 설명보다는 직접 숫자를 수정해 가며 결과로 확인하는 것이 낫다. 

 

@keyframe, animation을 사용해서 svg 이미지가 움직일 수 있도록 css를 작성한다.

<style lang="scss" scoped>
@keyframes loading {
  0% {
    stroke-dashoffset: 192;
  }
  100% {
    stroke-dashoffset: 0;
  }
}

.kv-swiper {
  position: relative;
  height: 300px;

  .swiper-container {
    height: 100%;

    .swiper-slide {
      ...
    }
  }

  .kv-function {
    position: absolute;
    left: 50%;
    bottom: 30px;
    z-index: 1;
    transform: translateX(-50%);

    .swiper-autoplay {
      ...
    }

    .swiper-pagination::v-deep {
      position: relative;

      .swiper-pagination-bullet {
        width: 10px;
        height: 10px;
        margin: 0 5px;
        background-color: #fff;
        opacity: 1;
        cursor: pointer;

        svg {
          display: none;
          transform: rotate(-90deg);

          .pagination-loader {
            stroke-dasharray: 192;
            stroke-dashoffset: 192;
            animation: loading 5s linear infinite;
          }

          .pagination-circle {
            stroke-opacity: 0.2;
          }
        }
      }

      .swiper-pagination-bullet-active {
        width: 24px;
        height: 15px;
        background-color: transparent;

        svg {
          display: block;
        }
      }

      &.stop {
        .swiper-pagination-bullet {
          svg {
            .pagination-loader {
              stroke: none;
              animation-play-state: paused;
            }
          }
        }
      }
    }
  }
}
</style>

+ Recent posts