Skip to main content
Uncategorized

Vuetify v-expansion-panels: Understanding v-model Tracking Behavior Differences

By October 24, 2024No Comments

In Vuetify’s v-expansion-panels component, there’s a significant difference in how v-model tracks selected panels between versions 2 and 3. Let’s explore this behavior:

Vuetify 2 Behavior

In Vuetify 2, v-model only tracks by index regardless of what you set as the 

1
:key
:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- v-model ONLY tracks by index regardless of :key -->
<v-expansion-panels v-model="selectedIndex">
    <v-expansion-panel
        v-for="(item, index) in items"
        :key="item.value"  <!-- This doesn't affect v-model behavior -->
    >
        <v-expansion-panel-header>
            <div :class="{ 'active': selectedIndex === index }">
                {{ item.text }}
            </div>
        </v-expansion-panel-header>
    </v-expansion-panel>
</v-expansion-panels>

<script>
export default {
    data: () => ({
        selectedIndex: null  // Will be 0, 1, 2, etc.
    }),
    computed: {
        selectedValue() {
            return this.items[selectedIndex]?.value;
        }
    }
}
</script>

The Gotcha

  • The v-model tracks by index (0, 1, 2, etc.)
  • The 
    1
    :key
     binding has no effect on tracking
  • Need a computed property to get the actual value

Vuetify 3 Behavior

Vuetify 3 introduces value tracking through the 

1
:value
 prop:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- Can track by actual value using :value prop -->
<v-expansion-panels v-model="selected">
    <v-expansion-panel
        v-for="item in items"
        :key="item.id"
        :value="item.id"  <!-- v-model will track this value -->
    >
        <v-expansion-panel-header>
            {{ item.text }}
        </v-expansion-panel-header>
    </v-expansion-panel>
</v-expansion-panels>

<script>
export default {
    data: () => ({
        selected: null  // Will be actual item.id value
    })
}
</script>

Improvements

  • Can track by custom values using 
    1
    :value
     prop
  • Directly stores the selected value in v-model
  • No need for computed properties to get actual values
  • More intuitive value tracking

Best Practices

Vuetify 2

  • Name variables to clearly indicate index tracking (e.g., selectedIndex)
  • Use computed properties to get actual values
  • Be explicit about index-based tracking in code comments

Vuetify 3

  • Can use semantic names for v-model variables
  • Utilize the 
    1
    :value
     prop for direct value tracking
  • More straightforward implementation

This change in Vuetify 3 represents a significant improvement in the developer experience, making the component behavior more intuitive and requiring less boilerplate code.

Close Menu