Vuetify 4.1.10, Vue 3.5.41, Vite production build (vite build && vite preview).
Two identical Wrapper.vue (<div><slot/></div>, compiled template SFC) instances with
render counters in their slot content: one OUTSIDE <v-app> (direct child of App's
template), one INSIDE <v-app><v-container>. Plus counters in a plain h() child,
the table's #bottom slot, and every row's #item.renders slot.
Steps: 3 clicks on an unrelated native <input v-model="dummy">, then 1 row-checkbox click.
| counter | baseline | after 3 unrelated toggles | after 1 selection click |
|---|---|---|---|
| Wrapper OUTSIDE v-app | 1 | 1 | 1 |
| Wrapper INSIDE v-app | 1 | 4 | 5 |
| plain h() child (inside) | 1 | 4 | 5 |
| v-data-table #bottom slot | 1 | 4 | 5 |
| every row #item.renders | 1 | 4 | 5 |
Conclusions:
- Vue's stable-slot gating works: the outside wrapper never re-renders even though App itself re-renders on every toggle (the v-model input is in App's template).
- The identical wrapper inside the Vuetify tree re-renders on every unrelated root update — the cascade is introduced by the Vuetify layer, not by Vue.
- The selection click also re-renders the inside wrapper: with
v-modelon the table in the root component, selection triggers the app-wide cascade in addition to the selection-Set row fan-out.