[Vuejs]-Using v-for for fixed numbers and not objects

1👍

Running methods inside the template leads to some infinite rendering loops since the variable is also used in template, to avoid this create a two-dimensional array as a computed property and then render it :

computed:{
   arr(){
    let n=0;
   return [...Array(20)].map((_,i)=>[...Array(5)].map((_,j)=>{
       ++n;
      return n;
   }))
 
  }
}

in template :

<tr v-for="(row,i) in arr" :key="i">
    <td v-for="col in row" :key="col">
        {{ col }}
    </td>
</tr>

1👍

You are changing numberCount (which is a reactive data property) directly in the template. That triggers a re-render (and thus an infinite loop). You can simply do this :

var app = new Vue({
  el: '#app',
  data: {
    totalColumns: 5,
    totalRows: 20
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <table border=1>
    <tr v-for="(row, rowIndex) in totalRows" :key="row">
        <td v-for="(col, columnIndex) in totalColumns" :key="col">
          {{ rowIndex * totalColumns + col}}
        </td>
    </tr>
  </table>
</div>
👤Namysh

1👍

The getTableNum function execution changes the numberCount in data and it triggers Vue to re-render the template, which causes the function execution, and so on.

In this case, you should try to avoid altering the numberCount value.

If I didn’t get you wrong, you wish to have 1-2-3-4-5 in the first row, 6-7-8-9-10 in the second, and so on.

If so, you can try to rewrite your function as such:

getTableNum(row, col) {
    // row and col are 1-based
    return 1 + ((row - 1) * this.totalColumns) + (col - 1);
},

1👍

Another alternative ONLY for static tables (where the table content is not modified after initial rendering) is the use of v-once directive. Each table row will be rendered only once, and every subsequent call to getTableNum function will not trigger the rerendering of previous rows:

var app = new Vue({
  el: '#app',
  data: {
    totalColumns: 5,
    totalRows: 20,
    numberCount: 0
  },
  methods: {
    getTableNum() {
      return ++this.numberCount
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <table border=1>
    <tr v-once v-for="(row, rowIndex) in totalRows" :key="row">
        <td v-for="(col, columnIndex) in totalColumns" :key="col">
         {{ getTableNum() }}
        </td>
    </tr>
  </table>
</div>

Leave a comment