Activate a function when the v-data-table in Vuetify is expanded and then collapsed

While trying to create a v-data-table, I came across some odd behavior when monitoring the expanded.sync value. The first layer's expanded.sync value seems normal, but the second layer's expanded.sync has three consecutive identical records.

I want to keep an eye on this value and perform actions when collapsing the expanded item. Is there a way to detect when the expanded items are collapsed?

Code for the top layer:

<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>

Code for the second layer:

<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 output after expanding and collapsing one item in each layer:

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 for your assistance!

Answer №1

It is recommended to avoid using a watch and instead listen for the item-expanded event specifically designed 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);
  }
}

When triggered, this event provides an object containing an item and value property. The item represents the row's data, and value indicates whether the row is currently expanded.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Why does json_encode() work for one string and fail for another?

UPDATE: Resolved the issue. Initially, someone left a comment with a solution that was later deleted. Interestingly, simply adding semi-colons after the two json_encode lines fixed the problem. I'm still puzzled as to why string1 worked without a clo ...

Update the Ngrx reducer when the component is present on the page

One dilemma I am facing involves managing two components within a page - an update user form and a history of events. Each component has its own reducer (user and events). My goal is to update the list of events in the store through an API call once the us ...

In HTML, adjust column widths for multiple tables according to the widest column present in any of them

With Python, I am creating an HTML page that contains multiple tables with the same number of columns, all holding the same type of data. While the generated page is functional, I would like to improve readability by ensuring that all tables have the same ...

The Math.random() function is responsible for producing a single random number

I have a unique idea for a keyboard that generates divs when keys are pressed. The keyboard functionality has already been implemented. Each div should be positioned randomly on the screen but still be grouped by letter. My approach involves adding a rando ...

What is the best way to utilize this resulting value as an input?

I am trying to generate a random number using math.random and use that value in the following script: let bday = Math.floor( Math.random() * (30 - 1 + 1) + 1 ); await test.page.select('select[name="day_select"]',bday); However, I am ...

Display a Vue pie chart after a brief delay, similar to revealing a warning message in the console

I have encountered an issue with filling a pie chart in my Vue application. Even though I am able to fill data into it correctly, the pie chart does not show up immediately on the page. Instead, it appears after some time as if triggered by a console log. ...

Issues persist with $.getJSON

I apologize if this question has been addressed previously, but I couldn't find the answer I was seeking. My issue involves using $.getJSON to send variables to a PHP file. Although the file returns success as true, it always triggers the .fail functi ...

Reactjs slider causes unexpected useState behavior

I created an autoplay Slider with three cards using the useEffect hook. However, the manual "previous" and "forward" buttons are not functioning correctly. The useState function is not updating values as expected, leading to unexpected changes in state. ...

How can data be transferred from a parent to a child component in Angular?

I'm facing an issue trying to pass the selected value from a dropdownlist in a user interface. I have a parent component (app.component.html) and a child component (hello.component.html & hello.component.ts). My goal is to transfer the option val ...

Change the position of an array element when displayed on an HTML page

I'm trying to figure out a way to manipulate the position of an HTML element that is stored inside an array. The issue I am facing is that my code generates a new div every time a specific function is called, and this div has a class applied to it for ...

What is the best way to eliminate mouse click release events?

Encountering an issue with my Vue/Vuetify Dialog that closes when clicking outside of it as expected. The problem arises when there is a text field inside the dialog. If I accidentally select the content and release the mouse outside of the dialog, it als ...

Is there a way to determine if a specific string matches a value within an object?

Within my codebase, there exists an object named "codes": var codes = { code1: 'test1' code2: 'test2' } I am looking to determine if this object possesses a specific property and then display the result in the console. if(inp ...

Is there a term in JavaScript that denotes an object that can be serialized into JSON format?

Can you help me find a term for basic objects that accentuates their simplicity? Particularly, objects that do not reference themselves and do not have any methods or bindings (i.e. JSON-serializable). The terms I am currently using are: "flat object" " ...

Embed schema information into HTML tags using JavaScript

Is there a way to insert text, specifically schema data, into an HTML div tag using JavaScript? While I know how to modify existing values within a tag like class, href, and title, I am struggling to find a method to add something entirely new. Essentiall ...

How are objects typically created in Node.js applications?

These code snippets are from Node.js tests, and I am curious about why one method of instantiating an object is favored over another? // 1 var events = require('events'); var emitter = new events.EventEmitter(); emitter.on('test', doSo ...

Is there a way to choose multiple dropdown items that share the same header?

Utilizing the Fluent UI React Northstar Dropdown component in my React project, I've encountered an issue with multiple item selection. It seems that when there are several items sharing the same header value, only one can be selected at a time. What ...

The Angular controller encountered an unexpected token

I have organized all my Angular controllers in one controller file. However, I encountered an issue when trying to print out a specific part of my object array at the end of a controller. Everything worked fine until I added a new controller after the cur ...

Tips for creating an HTML page with the dimensions of an A4 paper sheet?

My goal is to display the HTML page in a browser while containing the content within the dimensions of an A4 size page. Additionally, when printed, the HTML page should be formatted to fit onto A4-sized paper pages. <div classNa ...

Unable to refresh HTML table using Vuex data in Vue JS

I am new to working with Vue.js and particularly Nuxt. I am facing an issue with updating a table using data fetched from the backend. Even though I can see the data in the Vuex tab when the page loads, I cannot seem to populate the table with it. The func ...

return to the original secured page based on the most recent language preference

I'm facing an issue with a logical redirection that needs to redirect users to the previous protected page after login. The login functionality is implemented using my custom login page and Google Credentials. Additionally, I have set up a multilingu ...