codersrb
codersrb

Reputation: 140

Close and Reopen a parent div in a vue js for loop

<div>
  <b-card-group :columns="layout == 'masonry'" :deck="layout == 'grid'">
    <b-card
        v-for="(image, imageIndex) in images"
        :key="imageIndex"
        :img-src="image"
        img-top>
    </b-card>
  </b-card-group>
</div>

I'm using VueJS to render this component. I have an array of image URLs in images data, I'm looping it over in a component (Bootstrap Card), what I want is, I want to close the parent <b-card-group/> for every third iteration of the loop and reopen it again so that I can have a group of 3 <b-card/> inside 1 <b-card-group/>

So for 9 images, I will end up with 3 <b-card-group/> and 3 <b-card/> in each block.

How do I achieve this in Vue JS?

Upvotes: 1

Views: 375

Answers (2)

Dan
Dan

Reputation: 63059

Since you're using Bootstrap Vue, you can avoid doing it programatically and take advantage of the library's Layout & Grid system.

Create one <b-row> and iterate the <b-col> elements, which will self-arrange according to the row's cols attribute. You could also use different column amounts at different screen size breakpoints.

Here's an example that uses 1 column at the smallest breakpoint and 3 for the rest:

<b-card-group>
  <b-row cols="1" cols-sm="3">
    <b-col v-for="(image, imageIndex) in images" :key="imageIndex">
      <b-card
        :img-src="image"
        img-top
      >
      </b-card>
    </b-col>
  </b-row>
</b-card-group>

No JavaScript necessary.

Upvotes: 0

tony19
tony19

Reputation: 138216

Use a computed property to restructure images into a 3x3 array (named "imageGroups"):

export default {
  computed: {
    imageGroups() {
      let curr = -1
      const groups = []
      const images = this.images
      for (let i = 0; i < images.length; i++) {
        if (i % 3 === 0) {
          curr++
        }
        groups[curr] = groups[curr] || []
        groups[curr].push(images[i])
      }
      return groups
    }
  }
}

Then, use a nested v-for on imageGroups in your template to render the groups:

<div v-for="group in imageGroups">
  <b-card-group>
    <b-card v-for="img in group" :img-src="img.src">
    </b-card>
  </b-card-group>
</div>

demo

Upvotes: 1

Related Questions