Trigger a method when v-data-table expanded is collapsed in Vuetify

Viewed 1824

I tried to construct a v-data-table and observed very strange behaviour while watching the expanded.sync value. The 1st layer expanded.sync value looks normal, but the 2nd layer expanded.sync has 3 consecutive same records.

I intend to watch this value, do something when collapsing the expanded item. Is there are any solution to detect when the expanded items are collapsed?

Top layer code

<template>
  <v-data-table
    :headers="headers"
    :items="desserts"
    item-key="name"
    :expanded.sync="itemExpanded"
    show-expand>
  >
    <template v-slot:top>
      <v-toolbar height="38" falt color="#cddde1">
        <v-toolbar-title dense> Test </v-toolbar-title>
      </v-toolbar>
    </template>
      <template v-slot:expanded-item="{headers}">
        <td :colspan="headers.length">
          <Show2></Show2>
        </td> 
      </template>
  </v-data-table>
</template>
<script>
import Show2 from "./ShowTest2.vue";
export default {
  name: "Show1",
   components: {
      Show2
  },
   data: () => ({
     itemExpanded:[],
    desserts: [
      {
        name: 'Show 1 - item 1',
        calories: 237,
        fat: 9.0,
        carbs: 37,
        protein: 4.3,
        iron: '1%',
      },
      {
        name: 'Show 1 - item 2',
        calories: 262,
        fat: 16.0,
        carbs: 23,
        protein: 6.0,
        iron: '7%',
      },
    
    ],
    headers: [
      {
        text: 'Dessert (100g serving)',
        align: 'start',
        sortable: false,
        value: 'name',
      },
      { text: 'Calories', value: 'calories' },
      { text: 'Fat (g)', value: 'fat' },
      { text: 'Carbs (g)', value: 'carbs' },
      { text: 'Protein (g)', value: 'protein' },
      { text: 'Iron (%)', value: 'iron' },
      { text: "details", value: "data-table-expand"  },
    ],
  }),
  watch: {
     itemExpanded(newVal,val){
      console.log('layer 1', newVal);
    },
  },
};
</script>

2nd layer code

<template>
  <v-data-table
    :headers="headers"
    :items="desserts"
    item-key="name"
    :expanded.sync="itemExpanded2"
    show-expand>
  >
    <template v-slot:top>
      <v-toolbar>
        <v-toolbar-title dense> Test2</v-toolbar-title>
      </v-toolbar>
    </template>
      <template v-slot:expanded-item="{headers}">
        <td :colspan="headers.length">
            
        </td> 
      </template>
  </v-data-table>
</template>
<script>
export default {
  name: "Show2",
   data: () => ({
     itemExpanded2:[],
    desserts: [
      {
        name: 'Show 2 - item 1',
        calories: 159,
        fat: 6.0,
        carbs: 24,
        protein: 4.0,
        iron: '1%',
      },
      {
        name: 'Show 2 - item 2',
        calories: 262,
        fat: 16.0,
        carbs: 23,
        protein: 6.0,
        iron: '7%',
      },
    ],
    headers: [
      {text: 'Dessert (100g serving)',align: 'start', sortable: false, value: 'name',},
      { text: 'Calories', value: 'calories' },
      { text: 'Fat (g)', value: 'fat' },
      { text: 'Carbs (g)', value: 'carbs' },
      { text: 'Protein (g)', value: 'protein' },
      { text: 'Iron (%)', value: 'iron' },
      { text: "details", value: "data-table-expand"  },
    ],
  }),
  watch: {
     itemExpanded2(newVal,val){
       console.log('layer2', newVal);
    },
  },
};
</script>

Console.log result on each layer one expand + one collapsing.

layer 1 [__ob__: Observer]
ShowTest.vue?cc9a:66 layer 1 [{…}, __ob__: Observer]
ShowTest2.vue?5475:56 layer2 [{…}, __ob__: Observer]
ShowTest2.vue?5475:56 layer2 [{…}, __ob__: Observer]
ShowTest2.vue?5475:56 layer2 [{…}, __ob__: Observer]
ShowTest2.vue?5475:56 layer2 [__ob__: Observer]
ShowTest2.vue?5475:56 layer2 [__ob__: Observer]
ShowTest2.vue?5475:56 layer2 [__ob__: Observer]

Thank you very much !

1 Answers

Instead of using a watch you should listen for the item-expanded event which is provided for this purpose.

<v-data-table
  :headers="headers"
  :items="desserts"
  item-key="name"
  :expanded.sync="itemExpanded"
  show-expand
  @item-expanded="onExpand"
>
methods: {
  onExpand({ item, value }) {
    console.log(item, value);
  }
}

This event returns an object with an item and value property. The item is the data for the row, and value is whether or not the row is expanded now.

Related