결과 화면

 

버전

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>

결과 화면

 

버전

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 컴포넌트를 import 한다.
  2. swiper.css를 import 한다.
  3. <Swiper>와 <SwiperSlier> 컴포넌트를 사용해 마크업을 한다.
    이때 prev, next 버튼과 페이지네이션은 <Swiper> 컴포넌트 밖에 작성한다. (안에 있으면 SwiperSlide와 같이 움직이기 때문에 밖으로 뺀다.)
  4. kvSwiperOptions을 작성한다.
    가장 많이 사용하는 속성은 slidesPerView(슬라이드가 몇 개씩 노출되는지), spaceBetween(슬라이드 간의 간격)이고, 이외의 다양한 속성들은 공식 문서를 참고한다. (https://swiperjs.com/demos)
  5. swiper.css는 기본적인 스타일만 제공하기 때문에 크기, 배경, 글자, 위치 등은 css를 추가로 작성한다.
<template>
  <section class="kv-swiper">
    <Swiper :options="kvSwiperOptions">
      <SwiperSlide>Slide 1</SwiperSlide>
      <SwiperSlide>Slide 2</SwiperSlide>
      <SwiperSlide>Slide 3</SwiperSlide>
      <SwiperSlide>Slide 4</SwiperSlide>
      <SwiperSlide>Slide 5</SwiperSlide>
    </Swiper>

    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>

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

<script>
import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
import 'swiper/css/swiper.css'

export default {
  name: 'SwiperPage',

  components: {
    Swiper,
    SwiperSlide
  },

  data() {
    return {
      kvSwiperOptions: {
        slidesPerView: 2,
        spaceBetween: 20,
        loop: true,
        navigation: {
          prevEl: '.swiper-button-prev',
          nextEl: '.swiper-button-next'
        },
        pagination: {
          el: '.swiper-pagination'
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.kv-swiper {
  position: relative;
  height: 300px;

  .swiper-container {
    height: 100%;

    .swiper-slide {
      ...
    }
  }

  .swiper-button-prev,
  .swiper-button-next {
    &::after {
      color: #333;
    }
  }

  .swiper-pagination::v-deep {
    bottom: -30px;
    width: 100%;

    .swiper-pagination-bullet {
      margin: 0 5px;
      cursor: pointer;
    }

    .swiper-pagination-bullet-active {
      background-color: #333;
    }
  }
}
</style>

+ Recent posts