3

So to explain why I need to do that : I've got a masonry of photos and I need to add an index to each of those photos.

The thing is I can't relie on the index of my v-for because sometimes it is on purpose an "empty case".

|---|---|---|
|   | 2 | 3 |
| 1 |---|---|
|   | 4 | 5 |
|---|---|---|
| 6 |   | 8 |
|---| 7 |---|
| 9 |   | 10|
|---|---|---|

The code looks like this.

<div v-for="(row, i) in rphotos" :key="i">
    <div v-for="(p, j) in row" :key="i*nbCol+j">
       <div v-if="p"
            :data-index="index" 
            class="g-item">
          <!-- Increment index there -->
       </div>
       <div v-else class="g-item g-empty" />
    </div>
</div>

However due to vuejs reactivity, my index will always be updated.

An other solution could perhaps be to check through a computed if on the row, g-item is not too a g-empty however I'm not even sure it is possible and yet dont see how precisely I could do this.

My best bet would be to increment a value on display as it is done in PHP template rendering like Smarty or Blade. But since javascript frameworks is meant to be reactive is there a way of doing that ?

Any idea is welcomed.

Baldráni
  • 4,066
  • 3
  • 41
  • 63
  • This is highly unclear, starting with "I've got a masonry", I have never heard this term in a computer programming context before. Also you say that a "solution could perhaps be to check through a computed" -- have you tried that and had a problem? If so could you please post the attempt. – Dexygen Dec 04 '19 at 10:48
  • @GeorgeJempty question edited :) – Baldráni Dec 04 '19 at 10:55
  • OK, had you tagged it with "Masonry" I could have looked up that tag to find out what it is. There are so many of these libraries to keep up with it is hard to keep up with all but the most common. I have added the "Masonry" tag to your question. – Dexygen Dec 04 '19 at 11:38

2 Answers2

2

It's not clear what your data looks like, but you can set an index to each item in rphotos before displaying them so you can then access that index inside the v-for with p.index:

<div v-for="(row, i) in rphotosFiltered">
    <div v-for="(p, j) in row">
       <div v-if="p.index !== null" :data-index="p.index"></div>
       <div v-else/>
    </div>
</div>
data(): {
  return {
    rphotos: [
      [
        {index: 1, item1: ''},
        {index: null, item2: ''}
      ], 
      [
        {index: 3, item3: ''}
      ]
    ]
  }
},
computed: {
  rphotosFiltered() {
    // modify "this.rphotos" list here the way you need it
    // return it
  }
}
AlekseyHoffman
  • 2,486
  • 1
  • 4
  • 18
2

Incrementing a variable during render requires using a method, which breaks reactivity. For this reason, I recommend calculating the index of each image before rendering. In general, the rendering process should be just that--rendering the data that is already there.

If you can't modify the array of image data to include an index property, you could use separate array or hash to store the index values. If the array of image data might be changed by code that is outside your component, you can use a watch to update the index values when the image data changes. In this case also be sure to use the created or mounted hook to initialize the index values when the component is loaded.

UPDATE

Instead of initializing the index values using the created or mounted hook, simply set the immediate property of the watch. This forces it to run when the component is loaded as well as when the watched value changes.

Jason Smith
  • 973
  • 5
  • 17