Use Vue.js to slide and display HTML, images, and strings

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>

<div id="app">
  <v-slider :items="numbers"></v-slider>

  <v-slider :items="images">
    <img slot-scope="{ item }" :src="item">
  </v-slider>

  <v-slider :items="strings">
    <component
      slot-scope="{ item, index }"
      :is="`h${strings.length - index}`"
      v-text="item"
    ></component>
  </v-slider>
</div>

CSS

.v-slider {
  border: 2px solid black;
  margin: 5px;
  padding: 5px;
}

.v-slider-content {
  overflow: hidden;
}

.slide-change-enter-active,
.slide-change-leave-active {
  transition: 0.5s ease;
}

.slide-change-enter,
.slide-change-leave-to {
  transform: translate(100%);
  opacity: 0;
}

.slide-change-leave,
.slide-change-enter-from {
  transform: translate(0px);
  opacity: 1;
}

.active {
  background: red;
  color: white;
}

img {
  height: 200px;
}

JavaScript

Vue.component('v-slider', {
  template: `
<div class="v-slider" v-if="item != null">
  <div class="v-slider-content">
    <transition name="slide-change" mode="out-in">
      <div :key="index">
        <slot :item="item" :index="index">{{ item }}</slot>
      </div>
    </transition>
  </div>
  <div class="v-slider-navigation">
    <button @click="goTo(index - 1)">&lt;</button>
    <button
      v-for="i in items.length"
      v-text="i"
      :class="{ active: index === i - 1 }"
      @click="goTo(i - 1)"
    ></button>
    <button @click="goTo(index + 1)">&gt;</button>
  </div>
</div>`,
  props: [ 'items' ],
  data: () => ({
    index: 0,
  }),
  computed: {
    item() {
      return this.items[this.index];
    },
  },
  methods: {
    goTo(index) {
      const { items: { length } } = this;
      this.index = (index + length) % length;
    },
  },
});

new Vue({
  el: '#app',
  data: () => ({
    numbers: Array.from({ length: 7 }, (_, i) => ++i ** i),
    strings: [ 'hello, world!!', 'fuck the world', 'fuck everything' ],
    images: [
      'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Richard_Nixon_presidential_portrait_%281%29.jpg/250px-Richard_Nixon_presidential_portrait_%281%29.jpg',
      'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/TRUMAN_58-766-06_%28cropped%29.jpg/250px-TRUMAN_58-766-06_%28cropped%29.jpg',
      'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Theodore_Roosevelt_by_the_Pach_Bros_%284x5_cropped%29.jpg/250px-Theodore_Roosevelt_by_the_Pach_Bros_%284x5_cropped%29.jpg',
      'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/James_Buchanan.jpg/250px-James_Buchanan.jpg',
      'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/James_Monroe_White_House_portrait_1819_%28cropped_3x4_close%29.jpg/250px-James_Monroe_White_House_portrait_1819_%28cropped_3x4_close%29.jpg',
    ],
  }),
});