[Vuejs]-How to Increment Table Index in Nested Loop (Vue.js 3)

0👍

Solution

You need a function that determines the position of a specific child element within a certain parent element in an array. If you’re interested in the parent’s position, then the child element index should be -1 (so that in the code, we know this is not a real child, and when we increment it by +1, it remains at 0, thus not affecting the result).

const getNo = (array, parentIndex, childIndex = -1) => {
  // Start 0
  let number = 0;

  // Adding child counts of previous elements 
  for (let i = 0; i < parentIndex; i++) {
    const parent = array[i];
    if (!parent) break;

    number += parent.childs.length;
  }

  // Adding parentIndex
  number += parentIndex + 1;
  // Adding childIndex (if -1 then 0 = skip)
  number += childIndex + 1;

  return number;
}

Or, if you prefer shorter solutions, you can also use Array.propery.reduce().

const getNo = (array, parentIndex, childIndex = -1) => array.reduce((total, parent, index) => index < parentIndex && parent ? total + parent.childs.length : total, 0) + parentIndex + 1 + childIndex + 1;

Example

// CDN Vue Import
const { createApp, ref } = Vue

const app = createApp({
  setup() {
    const data = [{
      id: 1,
      name: "parent 1",
      childs: [{
        id: 2,
        name: "child 1-1"
      }, {
        id: 10,
        name: "child 1-2"
      }]
    }, {
      id: 4,
      name: "parent 2",
      childs: [{
        id: 6,
        name: "child 2-1"
      }, {
        id: 7,
        name: "child 2-2"
      }, {
        id: 8,
        name: "child 2-3"
      }]
    }, {
      id: 31,
      name: "parent 3",
      childs: [{
        id: 32,
        name: "child 3-1"
      }, {
        id: 310,
        name: "child 3-2"
      }]
    }]
    
    const getNo = (array, parentIndex, childIndex = -1) => {
      // Start 0
      let number = 0

      // Adding child counts of previous elements 
      for (let i = 0; i < parentIndex; i++) {
        const parent = array[i]
        if (!parent) break

        number += parent.childs.length
      }

      // Adding parentIndex
      number += parentIndex + 1
      // Adding childIndex (if -1 then 0 = skip)
      number += childIndex + 1

      return number
    }
    
    return { data, getNo }
  },
}).mount('#app')
<script src="https://unpkg.com/vue@3.3.4/dist/vue.global.prod.js"></script>

<div id="app">
  <table>
    <thead>
      <tr>
        <th>No.</th>
        <th>Parent</th>
        <th>Child</th>
      </tr>
    </thead>

    <tbody>
      <template v-for="(parent, parentIndex) in data" :key="parent.id">
        <tr>
          <td>{{ getNo(data, parentIndex) }}</td>
          <td>{{ parent.name }}</td>
          <td></td>
        </tr>
        <template v-for="(child, childIndex) in parent.childs" :key="child.id">
          <tr>
            <td>{{ getNo(data, parentIndex, childIndex) }}</td>
            <td></td>
            <td>{{ child.name }}</td>
          </tr>
        </template>
      </template>
    </tbody>
  </table>
</div>

Leave a comment