Vincent Desrosiers
Vincent Desrosiers

Reputation: 170

Problem with expandable child component in parent v-data-table using Vuetify 2

I upgraded to Vuetify 2 from 1.5. Everything went pretty smoothly except for one thing. I have a parent component with a v-data-table and I want to pass data and expand each row with a child component.

ScanGrid(parent component):

<template>
  <v-container>
    <v-card>
      <v-card-text>
        <v-layout row align-center>
          <v-data-table
            :headers="headers"
            :items="items"
            :hide-default-footer="true"
            item-key="id"
          >
            <template slot="items" slot-scope="props">
              <tr @click="props.expanded = !props.expanded">
                <td>{{ props.item.name }}</td>
                <td class="text-xs-left large-column">
                  {{ props.item.scanned }}
                </td>
                <td class="text-xs-left large-column">
                  {{ props.item.incoming }}
                </td>
                <td class="text-xs-left large-column">
                  {{ props.item.outgoing }}
                </td>
                <td class="text-xs-left large-column">
                  {{ props.item.unknown }}
                </td>
              </tr>
            </template>
            <template slot="expand" slot-scope="props">
              <ScanGridChild :value="props.item"></ScanGridChild>
            </template>
          </v-data-table>
        </v-layout>
      </v-card-text>
    </v-card>
  </v-container>
</template>

ScanGridChild(child component):

<template>
  <v-card>
    <v-card-text>{{ value }}</v-card-text>
  </v-card>
</template>

<script>
export default {
  name: "ScanGridChildComponent",
  props: {
    value: {
      Type: Object,
      Required: true
    }
  },
  computed: {},
  watch: {
    props: function(newVal, oldVal) {
      console.log("Prop changed: ", newVal, " | was: ", oldVal);
      this.render();
    }
  }
};
</script>

<style></style>

It worked fine in Vuetify 1.5.19. I'm on Vuetify 2.1.6 and using single file components. Thanks.

Upvotes: 1

Views: 2992

Answers (1)

chans
chans

Reputation: 5260

Vuetify 2.x has major changes to many components, slot-scopes are replaced with v-slot, and many new properties and slots added to vuetify data table

Here is the working codepen reproduced the same feature with above code

https://codepen.io/chansv/pen/BaaWbKR?editors=1010

You need to make sure that you have vue js 2.x and vuetify 2.x

Parent component code:

<template>
      <v-container>
        <v-card>
          <v-card-text>
            <v-layout row align-center>
              <v-data-table
                 :headers="headers"
                 :items="items"
                 item-key="name"
                 single-expand
                 :expanded="expanded"
                 hide-default-footer
                 @click:row="clickedRow"
               >
               <template v-slot:expanded-item="{ item }">
                 <td :colspan="headers.length">
                    <ScanGridChild :value="item"></ScanGridChild>
                 </td>
               </template>
             </v-data-table>
           </v-layout>
          </v-card-text>
        </v-card>
      </v-container>
    </template>


    <script>
    export default {
    ...
    data () {
        return {
        expanded: [],
        headers: [
          {
            text: "Localisation",
            sortable: true,
            value: "name"
          },
          {
            text: "Paquets scannés",
            sortable: true,
            value: "scanned"
          },
          {
            text: "Paquets entrants",
            sortable: true,
            value: "incoming"
          },
          {
            text: "Paquets sortants",
            sortable: true,
            value: "outgoing"
          },
          {
            text: "Paquets inconnus",
            sortable: true,
            value: "unknown"
          }
        ],
          items: [
          {
            id: 1,
            name: "Location 1",
            scanned: 159,
            incoming: 6,
            outgoing: 24,
            unknown: 4,
            test: "Test 1"
          },
          {
            id: 2,
            name: "Location 2",
            scanned: 45,
            incoming: 6,
            outgoing: 24,
            unknown: 4,
            test: "Test 2"
          }
        ],
        }
      },
      methods: {
        clickedRow(value) {
  if (this.expanded.length && this.expanded[0].id == value.id) {
    this.expanded = [];
  } else {
    this.expanded = [];
    this.expanded.push(value);
  }
}
      }
    ...
    }
    </script>

In child component

Replace

props: {
    value: {
      Type: Object,
      Required: true
    }
  },

with( Type and Required change to lower case type and required)

props: {
    value: {
      type: Object,
      required: true
    }
  },

Upvotes: 1

Related Questions