vue.jshtml-tablerowsv-for

vue.js v-for on two table rows


Vue 2, no webpack. I want to render two trs at a time, for main and detail expandable row. This is what I'm trying to achieve:

<table>
   <tbody>
     <div v-for="item in items">
         <tr></tr>
         <tr class="detail-row"></tr>
     </div>
   </tbody>
</table>

The problem is that <div> is an invalid child of tbody. How to render two <tr>s at each for loop iteration?


Solution

  • This is the way you solve it in browsers that support template.

    <table>
       <tbody>
         <template v-for="item in items">
             <tr></tr>
             <tr class="detail-row"></tr>
         </template>
       </tbody>
    </table>
    

    If you need to support browsers that do not support template, I typically resort to a render function.

    Here is a working example of both.

    console.clear()
    
    new Vue({
      el: "#app",
      data: {
        items: [{
            master: "Master",
            detail: "Detail"
          },
          {
            master: "Master",
            detail: "Detail"
          },
        ]
      }
    })
    
    new Vue({
      el: "#app2",
      data: {
        items: [{
            master: "Master",
            detail: "Detail"
          },
          {
            master: "Master",
            detail: "Detail"
          },
        ]
      },
      render(h){
        // build the rows
        let rows = []
        for (let item of this.items){
          rows.push(h("tr", [h("td", [item.master])]))
          rows.push(h("tr", {class: "detail-row"}, [h("td", [item.detail])]))
        }
        
        // add rows to body
        let body = h("tbody", rows)
        
        // return the table
        return h("table", [body])
      }
    })
    .detail-row{
     background-color: lightgray;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
    
    <h2>Using template</h2>
    <div id="app">
      <table>
        <tbody>
          <template v-for="item in items">
            <tr><td>{{item.master}}</td></tr>
            <tr class="detail-row"><td>{{item.detail}}</td></tr>
          </template>
        </tbody>
      </table>
    </div>
      
    <h2>Using render function</h2>
    <div id="app2"></div>