5+ Vue Carousel Examples

This post contains a total of 5+ Vue Carousel Examples with Source Code. All these Carousels are made using Vue.

You can use the source code of these examples with credits to the original owner.

Related Posts

Vue Carousel Examples

1. Vue Carousel

Made by Florence Bolsรฉe. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
<style>
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

h2 {
  font-size: 24px;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
  text-align: center;
  max-width: 600px;
  margin: 0 auto;
}

.carousel {
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}

.slide {
  flex: 0 0 100%;
  display: flex;
  justify-content: center;
  padding: 50px 0;
  transition: all .3s;
  background: #ddd;
  margin: 20px 0;
}

.carousel-controls__button {
  cursor: pointer;
  background: tomato;
  border: 0;
  color: #fff;
  border-radius: 3px;
  padding: 5px 10px;
  font-size: 18px;
}
</style>
</head>
<body>
  <div id="app">
  <h2>Carousel with Vue.js</h2>
  <div class="carousel-container">
    <transition-group class='carousel' tag="div">
      <div v-for="slide in slides" class='slide' :key="slide.id">
        <h4> {{ slide.title }} </h4>
      </div>
    </transition-group>
    <div class='carousel-controls'>
      <button class='carousel-controls__button' @click="previous">&#60;</button>
      <button class='carousel-controls__button' @click="next">&#62;</button>
    </div>
  </div>
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17-beta.0/vue.js'></script>
      <script>
new Vue({
  el: "#app",
  data: {
    slides: [
    {
      title: 'Slide 1',
      id: 1 },

    {
      title: 'Slide 2',
      id: 2 },

    {
      title: 'Slide 3',
      id: 3 },

    {
      title: 'Slide 4',
      id: 4 },

    {
      title: 'Slide 5',
      id: 5 }] },



  methods: {
    next() {
      const first = this.slides.shift();
      this.slides = this.slides.concat(first);
    },
    previous() {
      const last = this.slides.pop();
      this.slides = [last].concat(this.slides);
    } } });
    </script>
</body>
</html>

2. Vue carousel with Animation

Made by SparoSpace. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>
<link rel='stylesheet' href='https://fonts.googleapis.com/earlyaccess/cwtexhei.css.css'>
<style>
* {
  font-family: "cwTeXHei", serif;
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: #1c1c1c;
  margin: 0;
  padding: 0;
}

#app {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.postarea {
  width: 930px;
  height: 250px;
  white-space: nowrap;
}

.posts {
  height: 100%;
  position: relative;
  transition: 0.5s;
}

.post_box {
  display: inline-block;
  height: 100%;
}
.post_box .cover {
  width: 330px;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-left: 300px;
  margin-right: 300px;
  background-size: cover;
  background-position: center center;
  transition: 0.3s;
  cursor: pointer;
}
.post_box .cover:hover {
  width: 340px;
  height: 110%;
}
.post_box .cover:hover .infos {
  transform: translate(-220px, -10px);
}
.post_box .cover .infos {
  color: white;
  transform: translate(-200px, 0);
  text-shadow: 0px 0px 30px rgba(0, 0, 0, 0.3);
  transition: 0.3s;
}
.post_box .cover .infos * {
  margin: 0;
}
.post_box .cover .infos h1 {
  font-size: 40px;
  font-weight: 400;
  margin-bottom: 10px;
}
.post_box .cover .infos h5 {
  background-color: white;
  color: black;
  padding: 4px 12px;
  font-size: 20px;
  font-weight: 300;
  box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.3);
}

@keyframes fadeIn {
  0% {
    opacity: 0;
    transform: translate(30px, 0);
    filter: saturate(0);
  }
  100% {
    opacity: 1;
    transform: translate(0px, 0);
  }
}
@keyframes silceIn {
  0% {
    transform: translateX(-50px);
  }
  100% {
    transform: translateX(0px);
  }
}
.cur_item .cover {
  animation: fadeIn 1s ease both;
}
.cur_item .infos h5 {
  animation: silceIn 1s 0.1s ease;
}

.control_left, .control_right {
  width: 40px;
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
  border: solid 1px white;
  position: fixed;
  color: white;
  font-size: 30px;
  transition: 0.3s;
}
.control_left:hover, .control_right:hover {
  background-color: white;
  color: black;
}

.control_left {
  left: 50px;
}

.control_right {
  right: 50px;
}
</style>
</head>
<body>
  <div id="app" @keyup.13.native="delta(1)">
  <div class="postarea">
    <div class="posts" :style="computed_left">
      <div class="post_box" v-for="(w,id) in works" :class="{cur_item: id==now_index}">
        <div class="cover" :style="bg_css(w.cover)">
          <div class="infos">
            <h1>{{w.title}}</h1>
            <h5>{{w.description}}</h5>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="control_left" @click="delta(-1)"><i class="fa fa-angle-left"></i></div>
  <div class="control_right" @click="delta(1)"><i class="fa fa-angle-right"></i></div>
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js'></script>
      <script>
var works = [
{
  title: "ๅœจๆฐดไธญๅคฎ",
  description: "็”ทๅฅณ่ฟท้€”ๅœจๅคงๆตทไน‹ไธญ",
  cover: "https://unsplash.it/600/400?image=1083" },

{
  title: "ๆฒ–ๆณกๅ’–ๅ•ก",
  description: "็”จๆœ€็ถ“ๅ…ธ็š„ๆฟพ็ด™ๆฒ–ๆณก",
  cover: "https://unsplash.it/600/400?image=1060" },

{
  title: "็†Šๅœจ้‡Ž",
  description: "ๅญฉๅญ๏ผŒ้€™ๆ˜ฏไฝ ๅ€‘็š„ไธ–็•Œ",
  cover: "https://unsplash.it/600/400?image=1020" },

{
  title: "้นฟๅ…’",
  description: "ๅฏๆ„›็š„ๅฐ้นฟ",
  cover: "https://unsplash.it/600/400?image=1003" },

{
  title: "ๅŸŽๅ ก",
  description: "่ณ็ซ‹ๆ–ผๆž—ไธญ",
  cover: "https://unsplash.it/600/400?image=1040" }];



var vm = new Vue({
  el: "#app",
  data: {
    works: works,
    now_index: 0,
    span_width: 930 },

  computed: {
    computed_left: function () {
      var result = {
        "left": -this.now_index * this.span_width + "px" };

      // console.log(result);
      return result;
    } },

  methods: {
    delta(d) {
      this.now_index =
      (this.now_index + d + this.works.length) % this.works.length;
    },
    bg_css(url) {
      return {
        "background-image": "url(" + url + ")" };

    } } });
    </script>
</body>
</html>

3. Simple Vue carousel

Made by Luke Taylor. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
<style>
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
}

.carousel {
  background-color: #ddd;
  height: 100vh;
  position: relative;
}
.carousel > div {
  background-color: #000;
  color: #fff;
  width: 10vw;
  height: 10vw;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  line-height: 10vw;
  font-family: sans-serif;
  font-size: 6vw;
}
.carousel .dots {
  position: absolute;
  bottom: 0;
  padding: 5%;
  width: 100%;
}
.carousel .dots .dot {
  background-color: #000;
}
</style>
</head>
<body>
  <div id="app">
  <carousel>
    <!-- Numbers 1-10 in divs -->
    <div v-for="i in [...Array(10).keys()]">{{i+1}}</div>
  </carousel>
</div>
    <script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-1b93190375e9ccc259df3a57c1abc0e64599724ae30d7ea4c6877eb615f89387.js"></script>

  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js'></script>
      <script>
Vue.component('carousel-dot', {
  template: '<div class="dot" v-bind:style="style"></div>',
  data: () => ({ selected: false }),
  computed: {
    style: () => ({
      opacity: this.selected ? 1 : 0.5 }) } });




Vue.component('carousel-dots', {
  props: ['numDots'],
  template: '<div class="dots"><carousel-dot v-for="i in numDots"></carousel-dot></div>' });


// Items displayed in the carousel
Vue.component('carousel-item', {
  template: '<div class="carousel-item" v-bind:style="style" v-on:click="centerSelf"><slot></slot></div>',
  data: () => ({
    zIndex: 0,
    xtrans: 0,
    ytrans: 0,
    scale: 1,
    opacity: 1 }),


  computed: {
    style() {
      return {
        transition: 'transform 0.5s, opacity 0.5s',
        transform: this.transform,
        'z-index': this.zIndex,
        opacity: this.opacity };

    },

    transform() {
      return [
      `translate(${this.xtrans - 50}%, ${this.ytrans - 50}%)`,
      `scale(${this.scale})`].
      join(' ');
    } },


  methods: {
    centerSelf() {
      this.$parent.arrange(this.$parent.$children.indexOf(this));
    } } });



// Carousel component
Vue.component('carousel', {
  // Render function wraps all children in carousel-item components
  render(createElement) {
    return createElement(
    'div',
    {
      class: 'carousel',
      ref: 'carousel' },

    this.$slots.default.map(el => createElement('carousel-item', [el])));

  },

  data: () => ({}),

  // Begin by centering the first element in the carousel
  mounted() {this.arrange(0);},

  methods: {
    // http://stackoverflow.com/q/4467539
    _mod: (n, m) => (n % m + m) % m,

    // Distribute elements so that they align with the selected elemenent in the center
    arrange(centerIndex) {
      const center = this.$children[centerIndex];
      const half = (this.$children.length - 1) / 2;

      // Items that will be displayed to the left of the item at centerIndex
      const before = [];
      // Keep adding items before until half the non-centerIndex items have been added
      for (let i = centerIndex - 1; before.length < half; i--) {if (window.CP.shouldStopExecution(0)) break;
        // this._mod is used to emulate a toroidal array by mapping elements below index 0 or beyond
        // the max index to elements in the valid array range
        before.push(this.$children[this._mod(i, this.$children.length)]);
      }

      // Items that will be displayed to the right of the item at centerIndex
      window.CP.exitedLoop(0);const after = [];
      for (let i = centerIndex + 1; after.length < this.$children.length - before.length - 1; i++) {if (window.CP.shouldStopExecution(1)) break;
        after.push(this.$children[this._mod(i, this.$children.length)]);
      }


      // Position all elements


      // Position center
      window.CP.exitedLoop(1);center.xtrans = 0;
      center.scale = 1;
      center.opacity = 1;
      center.zIndex = Math.max(before.length, after.length) + 1;

      // Position elements to left and right
      [before, after].forEach((list, listIndex) => {
        // Tracks the amount by which the parent was translated
        let parentTrans = 0;

        // Apply styles for each element in selected list
        list.forEach((item, i) => {
          // Set size
          item.scale = 0.8 ** (i + 1);
          // Set x offset. Negative for before, positive for after
          const absolute = 105 * item.scale * 1.125 + parentTrans;
          parentTrans = absolute; // Update how much parent was translated by
          item.xtrans = (listIndex == 0 ? -1 : 1) * absolute;
          // Set opacity
          item.opacity = Math.max(1 - 0.25 * (i / 2 + 1) ** 2, 0);
          // Set z-index
          item.zIndex = Math.max(before.length, after.length) - i;
        });
      });
    } } });



const app = new Vue({
  el: '#app' });
    </script>
</body>
</html>

4. Vue Carousel Bootstrap Vue Cards

Made by David Hutto. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
  <link rel='stylesheet' href='https://unpkg.com/[email protected]/dist/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://unpkg.com/[email protected]/dist/bootstrap-vue.css'>
<style>
.row{
  margin-top:100px;
}
</style>
</head>
<body>
  <div id="app">
  <b-container>
    <b-row>
      <b-col cols="12">
        <carousel :perPage="3">
          <slide class="p-2">
            <b-card title="Card Title 1" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article">
              <b-card-text>
                Some quick example text to build on the card title and make up the bulk of the card's content.
              </b-card-text>
              <b-button href="#" variant="primary">Go somewhere</b-button>
            </b-card>
          </slide>
          <slide class="p-2">
            <b-card title="Card Title 2" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article">
              <b-card-text>
                Some quick example text to build on the card title and make up the bulk of the card's content.
              </b-card-text>

              <b-button href="#" variant="primary">Go somewhere</b-button>
            </b-card>
          </slide>
          <slide class="p-2">
            <b-card title="Card Title 3" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article">
              <b-card-text>
                Some quick example text to build on the card title and make up the bulk of the card's content.
              </b-card-text>

              <b-button href="#" variant="primary">Go somewhere</b-button>
            </b-card>
          </slide>
          <slide class="p-2">
            <b-card title="Card Title 4" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article">
              <b-card-text>
                Some quick example text to build on the card title and make up the bulk of the card's content.
              </b-card-text>

              <b-button href="#" variant="primary">Go somewhere</b-button>
            </b-card>
          </slide>
        </carousel>
      </b-col>
    </b-row>
  </b-container>
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js'></script>
<script src='https://unpkg.com/[email protected]/dist/bootstrap-vue.js'></script>
<script src='https://ssense.github.io/vue-carousel/js/vue-carousel.min.js'></script>
      <script>
new Vue({
  el: "#app",
  components: {
    'carousel': VueCarousel.Carousel,
    'slide': VueCarousel.Slide },


  data: {
    slide: 0,
    sliding: null },

  methods: {
    onSlideStart(slide) {
      this.sliding = true;
    },
    onSlideEnd(slide) {
      this.sliding = false;
    } } });
    </script>
</body>
</html>

5. The simplest Vue carousel

Made by Ada. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
<style>
@import url("https://fonts.googleapis.com/css?family=Crimson+Text");

/* FADE IN */
.fade-enter-active {
  transition: opacity 1s;
}
.fade-enter {
  opacity: 0;
}

/* GO TO NEXT SLIDE */
.slide-next-enter-active,
.slide-next-leave-active {
  transition: transform 0.5s ease-in-out;
}
.slide-next-enter {
  transform: translate(100%);
}
.slide-next-leave-to {
  transform: translate(-100%);
}

/* GO TO PREVIOUS SLIDE */
.slide-prev-enter-active,
.slide-prev-leave-active {
  transition: transform 0.5s ease-in-out;
}
.slide-prev-enter {
  transform: translate(-100%);
}
.slide-prev-leave-to {
  transform: translate(100%);
}

/* SLIDES CLASSES */

.blue {
  background: #4a69bd;
}

.red {
  background: #e55039;
}

.yellow {
  background: #f6b93b;
}

/* SLIDER STYLES */
body {
  overflow: hidden;
  margin: 0;
  font-size: 50px;
  font-family: "Crimson Text", sans-serif;
  color: #fff;
}

#slider {
  width: 100%;
  height: 100vh;
  position: relative;
}

.slide {
  width: 100%;
  height: 100vh;
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn {
  z-index: 10;
  cursor: pointer;
  border: 3px solid #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 70px;
  height: 70px;
  position: absolute;
  top: calc(50% - 35px);
  left: 1%;
  transition: transform 0.3s ease-in-out;
  user-select: none;
}

.btn-next {
  left: auto;
  right: 1%;
}

.btn:hover {
  transform: scale(1.1);
}
</style>
</head>
<body>
  <div id="slider">
  <transition-group tag="div" :name="transitionName" class="slides-group">
    <div v-if="show" :key="current" class="slide" :class="slides[current].className">
      <p>I'm {{slides[current].className}}!</p>
    </div>
  </transition-group>
  <div class="btn btn-prev" aria-label="Previous slide" @click="slide(-1)">
    &#10094;
  </div>
  <div class="btn btn-next" aria-label="Next slide" @click="slide(1)">
    &#10095
  </div>
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js'></script>
      <script>
var slider = new Vue({
  el: "#slider",
  data: {
    current: 0,
    direction: 1,
    transitionName: "fade",
    show: false,
    slides: [
    { className: "blue" },
    { className: "red" },
    { className: "yellow" }] },


  methods: {
    slide(dir) {
      this.direction = dir;
      dir === 1 ?
      this.transitionName = "slide-next" :
      this.transitionName = "slide-prev";
      var len = this.slides.length;
      this.current = (this.current + dir % len + len) % len;
    } },

  mounted() {
    this.show = true;
  } });
    </script>
</body>
</html>

6. Slider carousel

Made by Dima. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
  <meta name="viewport" content="width=device-width, initial-scale=1"> 
<style>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
#app {
  display: flex;
  height: 100vh;
}
.CROP {
  height: 96px;
  overflow: hidden;
  width: 100%;
  padding: 8px 0;
}
.Carousel {
  margin: auto;
  width: 480px;
}
.Carousel_chunk {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.Carousel .currImg {
  cursor: pointer;
}
.chunk_item {
  height: 80px;
  margin: 2px;
  padding: 2px;
  border: 1px solid transparent;
  cursor: pointer;
}
.chunk_item:hover {
  border: 1px solid #2196f3;
}
.chunk_item.CURR {
  background: #ffd700;
  outline: 2px solid #000;
  border-color: transparent;
}
.chunk_item img {
  display: inline-block;
  height: 100%;
}
.Carousel-controls {
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.Carousel-controls_dot,
.Carousel-controls svg {
  cursor: pointer;
}
.Carousel-controls svg:hover {
  fill: #ff0;
}
.Carousel-controls_dot {
  border-radius: 50%;
  width: 1.2rem;
  line-height: 1.2rem;
  text-align: center;
  background-color: #222;
  font-family: sans-serif;
  font-size: 0.5em;
  color: #fff;
}
.Carousel-controls_dot:hover {
  transform: scale(1.4, 1.4);
}
.Carousel-controls_dot.CURR {
  cursor: none;
  background-color: #ffd700;
  color: #000;
  font-weight: bold;
  transform: scale(1.4, 1.4);
}
.slide_next-enter-active,
.slide_prev-enter-active {
  transition: transform 0.3s;
}
.slide_next-enter {
  transform: translateX(100%);
}
.slide_prev-enter {
  transform: translateX(-100%);
}
.lightbox {
  cursor: pointer;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #616574 url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 10 10' fill='none' stroke-linecap='round' stroke-linejoin='round' stroke='gold'><line x1='4' y1='4' x2='6' y2='6' /><line x1='6' y1='4' x2='4' y2='6' /></svg>") top right no-repeat;
  display: flex;
}
.lightbox img {
  cursor: default;
  margin: auto;
  max-width: 90%;
  max-height: 100%;
}
.prev,
.next {
  position: absolute;
  top: 50%;
  width: 40px;
  height: 60px;
  margin: -30px 4% 0;
  background: #444 url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' fill='none' stroke-linecap='round' stroke-linejoin='round'><path stroke='gold' d='M6,2 L4,5 L6,8'/></svg>") center/cover no-repeat;
}
.prev:hover,
.next:hover {
  background-color: #222;
}
.next {
  right: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' fill='none' stroke-linecap='round' stroke-linejoin='round'><path stroke='gold' d='M4,2 L6,5 L4,8'/></svg>");
}
</style>
</head>
<body>
  <div id="app"> 
  <div class="Carousel">
    <div class="lightbox" v-show="lightboxActive" @click.self="lightboxActive=false; currLightboxImg = currImgIdx"><img :src="imgList[currLightboxImg].src"/>
      <div class="prev" @click="goToImg(currLightboxImg-1)"></div>
      <div class="next" @click="goToImg(currLightboxImg+1)"></div>
    </div><img class="currImg" :src="imgList[currImgIdx].src" @click="lightboxActive=true"/>
    <transition-group class="CROP" :name="transition_name" tag="div">
      <div class="Carousel_chunk" v-for="(chunk,i) in arrChunk" v-show="currSlide == i" :key="i">
        <div class="chunk_item" v-for="(item,j) in chunk" :key="j" @click="currImgIdx = j+(i*chunkSize)" :class="{CURR: item.src == imgList[currImgIdx].src}"><img :src="item.src"/></div>
      </div>
    </transition-group>
    <div class="Carousel-controls">
      <svg @click="prev" width="48" height="48" viewBox="0 0 24 24" fill="gold" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <circle cx="12" cy="12" r="10"></circle>
        <polyline points="12 8 8 12 12 16"></polyline>
        <line x1="16" y1="12" x2="8" y2="12"></line>
      </svg>
      <div class="Carousel-controls_dot" v-for="(dot, i) in arrChunk" :class="{CURR : currSlide == i}" @click="goToChunk(i)">{{i+1}}</div>
      <svg @click="next" width="48" height="48" viewBox="0 0 24 24" fill="gold" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <circle cx="12" cy="12" r="10"></circle>
        <polyline points="12 16 16 12 12 8"></polyline>
        <line x1="8" y1="12" x2="16" y2="12"></line>
      </svg>
    </div>
  </div>
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js'></script>
      <script>
const imgList = Array.from({ length: 33 }, (v, i) => ({ src: `//raw.githubusercontent.com/codrops/HoverEffectIdeas/master/img/${i + 1}.jpg` }));


const vm = new Vue({
  el: "#app",
  data() {
    return {
      chunkSize: 4,
      imgList: imgList,
      currSlide: 0,
      currImgIdx: 15,
      transition_name: "slide_next",
      lightboxActive: false,
      currLightboxImg: 15 };

  },
  watch: {
    currImgIdx(newVal) {
      this.currLightboxImg = newVal;
    } },

  computed: {
    arrChunk() {
      return Array.
      from({ length: Math.ceil(this.imgList.length / this.chunkSize) }, (v, i) =>
      this.imgList.slice(i * this.chunkSize, i * this.chunkSize + this.chunkSize));

    } },

  methods: {
    prev() {
      this.transition_name = "slide_prev";
      this.currSlide = this.currSlide == 0 ? this.arrChunk.length - 1 : this.currSlide - 1;
    },
    next() {
      this.transition_name = "slide_next";
      this.currSlide = this.currSlide == this.arrChunk.length - 1 ? 0 : this.currSlide + 1;
    },
    goToImg(n) {
      this.currLightboxImg = n < 0 ? this.imgList.length - 1 : n % this.imgList.length;
    },
    goToChunk(idx) {
      this.transition_name = idx < this.currSlide ? "slide_prev" : "slide_next";
      this.currSlide = idx;
    } } });
    </script>
</body>
</html>