0

I'm looking for a solution to create a sequencial counter for my nested loop. So I made this test:

<template>
  <div class="container">
    <ul>
      <li v-for="item in list" :key="item">{{ counter++ }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "Foo",
  data() {
    return {
      list: ["item 1", "item 2", "item 3"],
      counter: 0
    };
  }
};
</script>

But instead return 1,2,3, it return 303, 304, 305 and this warning:

You may have an infinite update loop in a component render function.

I known that I can use (item, index). But I have a nested loop in real code.

https://codesandbox.io/s/amazing-mcnulty-hou4p

This is the real situation nested loop:

<template v-for="ranking in daysImages[currentDay]['images']">
    <template v-for="image in ranking">
        <figure class="thumb"
            v-for="path in image.paths"
            :key="path"
            @click="openModal()"
            v-show="
            (selectHashTag === allHashTagsTitle || image['hashtags'].includes(selectHashTag)) &&
            (selectTag === allTagsTitle || image['tags'].includes(selectTag))"
        >
            <img :src="path | formatImageURL" alt="">
        </figure>
    </template>
</template>
13
  • 1
    Please let us see the real code, and let us know why you can't use (item, index), since a nested loop shouldn't break it. The loop appears because you're doing counter++ in the actual rendering. Commented Dec 17, 2019 at 13:19
  • And where do you want to use the index in that those 3 loops? Commented Dec 17, 2019 at 13:26
  • @Djip I need to store index inside a data-index attribute in <figure> tag Commented Dec 17, 2019 at 13:27
  • But which index? Index of ranking, image or path? I guess you don't need all 3 in one attribute right? Commented Dec 17, 2019 at 13:28
  • @Djip Index for total image sequence. That's why I can't use (ranking, index), (image, index) or (path, index). None of them consider the entire loop. Commented Dec 17, 2019 at 13:31

2 Answers 2

1

Instead of doing counter++ which increments it after each render, maybe you could use .indexOf(item) on your array to get the actual index of the item without using the Vue stuff ?

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the suggestion. But I can't deppend on loop object
1

You can make it with either using a non reactive property, or simply defining an index on each item before render:

For the latter:

  • You may flatMap your 2d array to 1d array (and you trivially access the id by its position in the array)
  • You can compute the id your self and assign it to every element, then render your grid as usual.

let Grid = {
    props: ['arr2d'],
    data () {
      return {
        arr1d: this.arr2d.flatMap(x=>x)
      }
    },
    template: `
      <ul>
        <li v-for="(fruit, counter) in arr1d">
          {{fruit}}: {{counter}}
        </li>
      </ul>
    `
  }
  let Grid2 = {
    props: ['arr2d'],
    data () {
      let z = 0
      return {
        indexedArray: this.arr2d.map((ranking, i) => {
          return ranking.map(im => {
            return { image: im, id: z++ }
          })
        })
      }
    },
    template: `
      <ul>
        <template v-for="ranking in indexedArray">
          <template v-for="({image, id}) in ranking">
            <li>{{image}}: {{ id }}</li>
          </template>
        </template>
      </ul>
    `
  }
  new Vue({
    components:{ Grid, Grid2 },
    template: `<div>
      <Grid :arr2d="[['apple','grodzi', 'orange'], ['lime', 'lemon']]"/>
      <Grid2 :arr2d="[['apple','grodzi', 'orange'], ['lime', 'lemon']]"/>
    </div>`,
    el:'#app'
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.