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>
    <span v-for="i in 7">{{ i ** i }}</span>
  </v-slider>

  <v-slider>
    <img v-for="n in images" :src="n">
  </v-slider>

  <v-slider>
    <h3>hello, world!!</h3>
    <h2>fuck the world</h2>
    <h1>fuck everything</h1>
  </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="content()[index]">
  <div class="v-slider-content">
    <transition name="slide-change" mode="out-in">
      <v-slide :key="index" :vnode="content()[index]" />
    </transition>
  </div>
  <div class="v-slider-navigation">
    <button @click="goTo(index - 1)">&lt;</button>
    <button
      v-for="i in content().length"
      v-text="i"
      :class="{ active: index === i - 1 }"
      @click="goTo(i - 1)"
    ></button>
    <button @click="goTo(index + 1)">&gt;</button>
  </div>
</div>`,
  components: {
    vSlide: {
      props: [ 'vnode' ],
      render(h) {
        return h('div', [ this.vnode ]);
      },
    },
  },
  data: () => ({
    index: 0,
  }),
  methods: {
    content() {
      return (this.$slots.default || []).filter(n => n.tag);
    },
    goTo(index) {
      const { length } = this.content();
      this.index = (index + length) % length;
    },
  },
});

new Vue({
  el: '#app',
  data: () => ({
    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',
    ],
  }),
});