Treeview
A compound component for building accessible hierarchical tree interfaces with expand/collapse and selection support.
Usage
The Treeview component provides a compound pattern for building accessible tree structures. It uses the createNested composable internally for hierarchical state management — tracking parent-child relationships, open/close state, and cascade selection.
Hierarchical Tree
A categorized tree with expand/collapse and multi-select checkboxes.
- Fruits
- Vegetables
- Bread
Anatomy
<script setup lang="ts">
import { Treeview } from '@vuetify/v0'
</script>
<template>
<Treeview.Root>
<Treeview.List>
<Treeview.Item>
<Treeview.Activator>
<Treeview.Cue />
Label
</Treeview.Activator>
<Treeview.Content>
<Treeview.Group>
<Treeview.Item>
<Treeview.Activator>Leaf</Treeview.Activator>
</Treeview.Item>
</Treeview.Group>
</Treeview.Content>
</Treeview.Item>
</Treeview.List>
</Treeview.Root>
</template>For trees with selection, add Treeview.Checkbox and Treeview.Indicator:
<script setup lang="ts">
import { Treeview } from '@vuetify/v0'
</script>
<template>
<Treeview.Root>
<Treeview.List>
<Treeview.Item>
<Treeview.Activator>
<Treeview.Cue />
</Treeview.Activator>
<Treeview.Checkbox>
<Treeview.Indicator />
</Treeview.Checkbox>
Label
<Treeview.Content>
<Treeview.Group>
<Treeview.Item>Leaf</Treeview.Item>
</Treeview.Group>
</Treeview.Content>
</Treeview.Item>
</Treeview.List>
</Treeview.Root>
</template>Configuration
Expansion Mode
Control how many nodes can be open at once with the open prop:
<template>
<!-- Default: multiple nodes can be open simultaneously -->
<Treeview.Root open="multiple" />
<!-- Accordion: only one node open at a time -->
<Treeview.Root open="single" />
</template>Use open-all to expand all nodes on mount:
<template>
<Treeview.Root open-all>
<!-- All nodes start expanded -->
</Treeview.Root>
</template>Selection Mode
The selection prop controls how selection propagates through the hierarchy:
| Value | Behavior |
|---|---|
cascade (default) | Selecting a parent selects all descendants; parents show tri-state when partially selected |
independent | Each node selected independently, no cascading |
leaf | Only leaf nodes can be selected; selecting a parent selects all its leaf descendants |
<template>
<Treeview.Root v-model="selected" selection="leaf">
<!-- Only leaf nodes appear in v-model -->
</Treeview.Root>
</template>Active Item
The active prop controls single vs. multi-highlight mode (independent of selection):
<template>
<!-- Default: only one item highlighted at a time -->
<Treeview.Root active="single" />
<!-- Multiple items can be highlighted simultaneously -->
<Treeview.Root active="multiple" />
</template>Reveal
Set reveal to automatically open all ancestor nodes when a descendant is opened. Useful for “navigate to item” patterns where a deep node is programmatically opened:
<template>
<Treeview.Root reveal>
<!-- Opening a deep node opens its entire ancestor chain -->
</Treeview.Root>
</template>Examples
Settings Panel
A settings tree with functional controls built from reactive data. Click any setting to activate it and view its description in the detail pane.
Activation —
activatefrom theItemslot highlights the current item. Style the active row with[data-active].Functional controls — toggles and
<select>dropdowns modify the reactive data directly.Disabled —
:disabledonTreeview.Itemgreys out the “Experimental” category. Style with[data-disabled].Depth indentation —
--v0-treeview-depthCSS variable on each item drivespadding-left, no manual nesting needed.Open/closed —
isOpenslot prop onItemrotates the chevron via a CSS class.Recursive rendering —
SettingNode.vuehandles both categories and leaves, recursing throughTreeview.Groupfor nested children.
Click a setting to see its description.
Recipes
Cascade Selection
Add v-model to Treeview.Root for cascade selection. Use Treeview.Checkbox and Treeview.Indicator for tri-state checkboxes. Use Treeview.SelectAll for a tree-wide toggle.
<script setup lang="ts">
import { Treeview } from '@vuetify/v0'
import { ref } from 'vue'
const selected = ref<string[]>([])
</script>
<template>
<Treeview.Root v-model="selected">
<Treeview.SelectAll>
<Treeview.Indicator />
Select All
</Treeview.SelectAll>
<Treeview.List>
<Treeview.Item value="users">
<Treeview.Checkbox>
<Treeview.Indicator />
</Treeview.Checkbox>
Users
<Treeview.Group>
<Treeview.Item value="users:view">
<Treeview.Checkbox>
<Treeview.Indicator />
</Treeview.Checkbox>
View
</Treeview.Item>
<Treeview.Item value="users:create">
<Treeview.Checkbox>
<Treeview.Indicator />
</Treeview.Checkbox>
Create
</Treeview.Item>
</Treeview.Group>
</Treeview.Item>
</Treeview.List>
</Treeview.Root>
</template>Styling with Data Attributes
All sub-components expose data attributes for CSS-driven state styling:
| Component | Attribute | Values |
|---|---|---|
| Item | data-selected | Present when selected |
| Item | data-disabled | Present when disabled |
| Item | data-open | Present when expanded |
| Item | data-active | Present when active |
| Activator | data-disabled | Present when disabled |
| Activator | data-open | Present when expanded |
| Checkbox | data-selected | Present when checked |
| Checkbox | data-disabled | Present when disabled |
| Checkbox | data-mixed | Present when indeterminate |
| Cue | data-state | open or closed |
| Indicator | data-state | checked, unchecked, or indeterminate |
The --v0-treeview-depth CSS variable is set on each Item, enabling indentation:
.tree-item {
padding-left: calc(var(--v0-treeview-depth) * 1rem);
}