Skip to content

UITreeSelect

UITreeSelect

UITreeSelect is a component that combines a dropdown select with a tree structure, allowing users to select options from hierarchical data. It’s ideal for selecting items from categories, folders, or any nested structure.

<template>
<UITreeSelect
v-model="selectedValue"
:options="treeData"
placeholder="Select an option"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedValue = ref(null);
const treeData = [
{
label: 'Parent 1',
value: 'parent1',
children: [
{ label: 'Child 1.1', value: 'child1.1' },
{ label: 'Child 1.2', value: 'child1.2' },
],
},
{
label: 'Parent 2',
value: 'parent2',
children: [
{ label: 'Child 2.1', value: 'child2.1' },
],
},
];
</script>

Props

  • modelValue (any): The selected value(s), to be used with v-model
  • options (Array): Tree data options
  • placeholder (string, default: ‘Please select’): Input placeholder text
  • disabled (boolean, default: false): Whether the component is disabled
  • clearable (boolean, default: false): Whether to show a clear button
  • multiple (boolean, default: false): Whether multiple selection is allowed
  • checkable (boolean, default: false): Whether to show checkboxes for selection
  • filterable (boolean, default: false): Whether the options can be filtered by search
  • showPath (boolean, default: false): Whether to show the full path in the selection
  • expandAll (boolean, default: false): Whether to expand all nodes by default
  • size (‘small’ | ‘medium’ | ‘large’, default: ‘medium’): Size of the component
  • loading (boolean, default: false): Whether the tree select is in loading state
  • loadingText (string, default: ‘Loading…’): Text to display during loading
  • emptyText (string, default: ‘No data’): Text to display when there are no options
  • valueField (string, default: ‘value’): Field name for option values
  • labelField (string, default: ‘label’): Field name for option labels
  • childrenField (string, default: ‘children’): Field name for children options
  • virtualScroll (boolean, default: false): Whether to use virtual scrolling for large datasets

Events

  • update:modelValue (value: any): Emitted when the selected value changes
  • focus (event: FocusEvent): Emitted when the component gains focus
  • blur (event: FocusEvent): Emitted when the component loses focus
  • clear (): Emitted when the clear button is clicked
  • search (searchValue: string): Emitted when the user types in the search input
  • node-expand (node: TreeNode): Emitted when a tree node is expanded
  • node-collapse (node: TreeNode): Emitted when a tree node is collapsed

Slots

  • prefix: Custom prefix content in the input
  • suffix: Custom suffix content in the input
  • empty: Custom empty content when no options are available
  • label (scoped slot with { node, selected }): Custom node label rendering
  • loading: Custom loading content

Usage Examples

  1. Basic Usage:
<template>
<UITreeSelect
v-model="value"
:options="options"
placeholder="Select category"
/>
</template>
<script setup>
import { ref } from 'vue';
const value = ref(null);
const options = [
{
label: 'Electronics',
value: 'electronics',
children: [
{ label: 'Phones', value: 'phones' },
{ label: 'Computers', value: 'computers' },
],
},
{
label: 'Clothing',
value: 'clothing',
children: [
{ label: 'Men', value: 'men' },
{ label: 'Women', value: 'women' },
],
},
];
</script>
  1. Multiple Selection:
<template>
<UITreeSelect
v-model="values"
:options="options"
placeholder="Select categories"
multiple
checkable
/>
</template>
<script setup>
import { ref } from 'vue';
const values = ref([]);
const options = [
// Tree options data...
];
</script>
  1. With Search Filtering:
<template>
<UITreeSelect
v-model="value"
:options="options"
placeholder="Search and select"
filterable
/>
</template>
  1. Showing Full Path:
<template>
<UITreeSelect
v-model="value"
:options="options"
placeholder="Select with path"
showPath
/>
</template>
  1. Custom Node Rendering:
<template>
<UITreeSelect
v-model="value"
:options="options"
placeholder="Custom nodes"
>
<template #label="{ node, selected }">
<div :style="{ fontWeight: selected ? 'bold' : 'normal' }">
<UIIcon :name="node.icon" v-if="node.icon" />
{{ node.label }}
<span v-if="node.count" class="count">({{ node.count }})</span>
</div>
</template>
</UITreeSelect>
</template>
<script setup>
const options = [
{
label: 'Projects',
value: 'projects',
icon: 'folder',
count: 5,
children: [
{ label: 'Project A', value: 'project-a', icon: 'file', count: 3 },
{ label: 'Project B', value: 'project-b', icon: 'file', count: 2 },
],
},
// More options...
];
</script>

Best Practices

  1. Data Organization:

    • Keep hierarchy depth reasonable (ideally 2-4 levels)
    • Use consistent naming conventions
    • Consider alphabetical ordering when appropriate
    • Include counts or metadata when helpful
  2. User Experience:

    • Use clear, descriptive labels
    • Consider expandAll for small trees
    • Enable filtering for large datasets
    • Show path when context is important
    • Use checkable mode for multiple selections
  3. Performance:

    • Enable virtual scrolling for large datasets
    • Implement lazy loading for very large trees
    • Optimize option rendering with custom slots
    • Consider collapsed state for initial rendering
  4. Accessibility:

    • Include aria labels for screen readers
    • Ensure keyboard navigation works properly
    • Provide sufficient color contrast
    • Use appropriate focus indicators