1

I have got a vuetify data table with expandable rows. When expanded, I want to show a data table within the expanded section that has the exact same columns as the main one. I am having trouble with aligning the columns, I just can't seem to align them.

I have tried adding another data table within the parent one, adding a full <table> or only <tr>s and/or <td>s but no luck.

The result so far is

nested tables

You can see that the nested table is not aligned with the parent one, the figures are out of place.

Here is where I got so far (CodePen):

<div id="app">
  <v-app id="inspire">
    <v-data-table
      :headers="headers"
      :items="reportData"
      :items-per-page="-1"
      :single-expand="false"
      :expanded.sync="expanded"
      class="elevation-1"
      show-expand
      item-key="id" 
    >
      <template v-slot:top>
        <v-toolbar flat>
          <v-toolbar-title>Report</v-toolbar-title>
          <v-spacer></v-spacer>
        </v-toolbar>
      </template>

      <template v-slot:expanded-item="{ headers, item }">
        <td :colspan="headers.length">
          <table style="width: 100%;">
            
            <tr v-for="row in item.events" :key="row.id">

              <td v-if="key != 'id'" v-for="(event, key) in row">{{row[key]}}</td>
              
            </tr>
          </table>
        </td>
      </template>
    </v-data-table>
  </v-app>
</div>

And

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      expanded: [],
      singleExpand: false,
      headers: [
        { text: 'Event Name', value: 'name'},
            { text: 'Total Hits', value: 'totalHits' },
            { text: 'Unique Hits', value: 'uniqueHits' },
            { text: '', value: 'data-table-expand' },
      ],
      reportData: [
    {
        "id": 294,
        "name": "Bounce",
        "totalHits": 40243,
        "uniqueHits": 14569,
        "events": [
            {
                "id": 411,
                "name": "Bounce",
                "totalHits": 40242,
                "uniqueHits": 14568
            },
            {
                "id": 562,
                "name": "",
                "totalHits": 1,
                "uniqueHits": 1
            }
        ]
    },
    {
        "id": 295,
        "name": "Return",
        "totalHits": 1763,
        "uniqueHits": 672,
        "events": [
            {
                "id": 412,
                "name": "Return",
                "totalHits": 1628,
                "uniqueHits": 623
            },
            {
                "id": 417,
                "name": "Push",
                "totalHits": 135,
                "uniqueHits": 49
            }
        ]
    },
    {
        "id": 402,
        "name": "Deadly Virus | Push",
        "totalHits": 69,
        "uniqueHits": 28,
        "events": [
            {
                "id": 561,
                "name": "No Action Needed",
                "totalHits": 69,
                "uniqueHits": 28
            }
        ]
    },
    {
        "id": 404,
        "name": "Returns",
        "totalHits": 17124,
        "uniqueHits": 2762,
        "events": [
            {
                "id": 409,
                "name": "Not a candidate",
                "totalHits": 5613,
                "uniqueHits": 384
            },
            {
                "id": 557,
                "name": "Sold Out",
                "totalHits": 11511,
                "uniqueHits": 2378
            }
        ]
    },
    {
        "id": 405,
        "name": "Deadly Virus | Push < Stage 1",
        "totalHits": 20,
        "uniqueHits": 16,
        "events": [
            {
                "id": 559,
                "name": "Unknow Source Added",
                "totalHits": 20,
                "uniqueHits": 16
            }
        ]
    },
    {
        "id": 411,
        "name": "Bad Test",
        "totalHits": 159,
        "uniqueHits": 103,
        "events": [
            {
                "id": 421,
                "name": "Yes",
                "totalHits": 9,
                "uniqueHits": 7
            },
            {
                "id": 568,
                "name": "No",
                "totalHits": 150,
                "uniqueHits": 96
            }
        ]
    },
    {
        "id": 462,
        "name": "New AMR",
        "totalHits": 1,
        "uniqueHits": 1,
        "events": [
            {
                "id": 623,
                "name": "Completed",
                "totalHits": 1,
                "uniqueHits": 1
            }
        ]
    },
    {
        "id": 472,
        "name": "Deadly Virus  | Push >Stage 1",
        "totalHits": 690,
        "uniqueHits": 159,
        "events": [
            {
                "id": 561,
                "name": "No Action Needed",
                "totalHits": 690,
                "uniqueHits": 159
            }
        ]
    },
    {
        "id": 473,
        "name": "Deadly Virus | Push < Stage 1 | Unknow Source Added",
        "totalHits": 75,
        "uniqueHits": 69,
        "events": [
            {
                "id": 559,
                "name": "Unknow Source Added",
                "totalHits": 75,
                "uniqueHits": 69
            }
        ]
    },
    {
        "id": 488,
        "name": "Inadequate",
        "totalHits": 7,
        "uniqueHits": 7,
        "events": [
            {
                "id": 623,
                "name": "Boom",
                "totalHits": 7,
                "uniqueHits": 7
            }
        ]
    }
],
      
    }
  },
})

EDIT

I got to the solution based on @Oleg's answer. Thanks @Oleg.

<td v-for="header in headers">
    <div class="use-case-breakdown-container">
        <div class="use-case-breakdown" v-for="actionObj in item.actions" :key="actionObj.id">
           <div v-for="prop in Object.keys(actionObj)">
             <span v-if="prop == header.value">
               {{actionObj[header.value]}}
             </span>
           </div>         
        </div>
    </div>
 </td>
4

1 回答 1

1

这是使用CSS Grid和不使用嵌套表(Codepen)的一种方法:

  <template v-slot:expanded-item="{ headers, item }">
    <td v-for="(header, parent_index) in headers">
      <div class="grid-container">
        <div class="grid-item" v-for="row in item.events" :key="row.id">
          <div v-for="(value, event, child_index) in row">
            <span v-if="parent_index + 1 === child_index"> {{ value }}</span>
          </div>
        </div>
      </div>
    </td>
   </template>

和 CSS:

.grid-container {
  display: inline-grid;
  grid-template-columns: auto;
  width: 100%;
}
于 2022-02-18T18:24:09.703 回答