[Vuejs]-Using Vue, Manually cycle through slides when using v-for with a computed array to set a max height

0👍

After a lot of trial and error I have found a solution. On mounted each slide is looped through. During each iteration we load the component, get is height compare it and then trigger nextSlide() and repeat. We set a timeout in the function to ensure the component has loaded when it gathers it’s height. When the current slide = the total slides we reset current slide back to 0 so we return to the first slide.

I also added a small loader while it is calculation heights to switching through the slide is not visible

<div
    ref="slide"
    class="slide card-body"
    :id="'slide-' + currentSlide"
    :key="'slide-' + currentSlide"
    :style="`height: ${slideHeight}px`">

   // Components load in here

</div>

data: function() {
return {
    currentSlide: 0,
    slideHeight: null
  }
},

async mounted () {
    this.slideHeight = await this.getHeight()
}

methods: {
    async getHeight () {
      let maxHeight = 0

      for(let item of this.data.body) {
        // Set a timeout to ensure components are loaded
        await this.timeOut(500)
        // Get the height of the slide once component is loaded into it
        let slide = this.$refs.slide
        let newHeight = slide.getBoundingClientRect().height
        // If newHeight isd greater than maxHeight maxHeight becomes newHeight
        maxHeight = newHeight > maxHeight ? newHeight : maxHeight
        // Switch the slide
        await this.nextSlide()
      }

      // if current slide equals quiz length reset it to 0 to begin the interactive
      if (this.currentSlide === this.data.body.length) {
        this.currentSlide = 0
        this.loader = false;
      }

      return maxHeight
    },

    timeOut (num) {
      return new Promise((resolve, reject) => {
        // Basic timeout function that will resolve when finished
        setTimeout(() => { resolve() }, num) 
      })
    },

    async nextSlide () {
      if (this.currentSlide < this.slideLength) {
        this.currentSlide++
      }
      return true
    },

}

Leave a comment