Tree
Ichki joylashgan ma’lumotlarni ko‘rsatuvchi iyerarxik daraxt ko‘rinishi komponenti; ochib/yopish, tanlash, checkboxlar, drag & drop, filtrlash, lazy loading, inline tahrirlash va boshqa ko‘plab imkoniyatlarga ega.
Basic
Tarmoq tugunini ochish yoki yopish uchun uning strelkasini bosing.
<script setup>
import { VxTree } from 'veloxui'
const data = [
{
key: '1', label: 'Documents',
children: [
{ key: '1-1', label: 'Work',
children: [
{ key: '1-1-1', label: 'Reports.xlsx' },
{ key: '1-1-2', label: 'Presentation.pptx' },
],
},
{ key: '1-2', label: 'Personal',
children: [
{ key: '1-2-1', label: 'Resume.pdf' },
],
},
],
},
]
</script>
<template>
<VxTree :data="data" />
</template>Selection
Tanlangan tugun kalitini bog‘lash uchun v-model:selected’dan foydalaning. Odatda yoqilgan.
Selected: none
<script setup>
import { ref } from 'vue'
const selectedKey = ref(null)
</script>
<template>
<VxTree :data="data" v-model:selected="selectedKey" />
</template>Multiple Selection
Bir nechta tugunni tanlash uchun multiple’ni yoqing. Ctrl (Mac’da Cmd) tugmasini bosib ushlab turib tugunlarni bosib tanlovni o‘zgartiring.
Selected: none
<script setup>
import { ref } from 'vue'
const selected = ref([])
</script>
<template>
<VxTree :data="data" v-model:selected="selected" multiple default-expand-all />
</template>Checkboxes
checkable bilan checkboxlarni qo‘shing. Qisman belgilangan ota tugunlar oraliq (indeterminate) holatni ko‘rsatadi.
Checked: none
<script setup>
import { ref } from 'vue'
const checkedKeys = ref([])
</script>
<template>
<VxTree :data="data" checkable v-model:checked="checkedKeys" default-expand-all />
</template>Show Lines
Ulovchi chiziqlarni show-line bilan ko‘rsating. solid, dashed yoki dotted tanlash uchun line-style’dan foydalaning.
<template>
<VxTree :data="data" show-line default-expand-all />
<VxTree :data="data" show-line line-style="dashed" default-expand-all />
<VxTree :data="data" show-line line-style="dotted" default-expand-all />
</template>Filter with Highlight
Ko‘rinadigan tugunlarni filtrlash uchun filter-text’dan foydalaning. Mos matn avtomatik ravishda ajratib ko‘rsatiladi. Daraxt mos kelgan bolalarni ko‘rsatish uchun avtomatik ochiladi va filtr olib tashlanganda oldingi holatiga qaytadi.
<script setup>
import { ref } from 'vue'
const filterText = ref('')
</script>
<template>
<VxInput v-model="filterText" placeholder="Type to filter..." />
<VxTree :data="data" :filter-text="filterText" default-expand-all />
</template>Default Expand All
Mount paytida har bir shoxni ochish uchun default-expand-all’dan foydalaning.
Accordion
Har bir darajada bir vaqtning o‘zida faqat bitta tugun ochilishi mumkin. Tugunni ochish uning yondosh (sibling) tugunlarini yopadi.
<template>
<VxTree :data="data" accordion />
</template>Node Icons
Tugun ma’lumotidagi icon xususiyatidan foydalaning yoki #icon slotida moslashtiring.
<script setup>
const data = [
{
key: 'src', label: 'src', icon: '📁',
children: [
{ key: 'index', label: 'index.ts', icon: '📄' },
{ key: 'styles', label: 'styles.css', icon: '🎨' },
],
},
{ key: 'pkg', label: 'package.json', icon: '📦' },
]
</script>
<template>
<VxTree :data="data" default-expand-all />
</template>To‘liq boshqaruv uchun #icon slotidan foydalaning:
<template>
<VxTree :data="data">
<template #icon="{ node, expanded }">
<MyIcon :name="node.children ? (expanded ? 'folder-open' : 'folder') : 'file'" />
</template>
</VxTree>
</template>Children Count
show-count yordamida bolalar soni bilan badge ko‘rsating. #count slotida moslashtiring.
<template>
<VxTree :data="data" show-count default-expand-all />
</template>Node Actions
Har bir tugunga hover paytida ko‘rinadigan amal tugmalarini qo‘shish uchun #actions slotidan foydalaning.
<template>
<VxTree :data="data" default-expand-all>
<template #actions="{ node }">
<button @click="editNode(node)">Edit</button>
<button @click="deleteNode(node)">Delete</button>
</template>
</VxTree>
</template>Drag & Drop
Tugunlarni qayta tartiblashga ruxsat berish uchun draggable’ni yoqing. node-drop hodisasi ma’lumotlarni yangilashingiz uchun dragNode, dropNode va position (before, inside yoki after)’ni beradi.
<script setup>
import { ref } from 'vue'
const data = ref([...])
function onDrop(info) {
console.log(info.dragNode.label, info.position, info.dropNode.label)
// Handle data mutation here
}
</script>
<template>
<VxTree :data="data" draggable @node-drop="onDrop" />
</template>Drag handle’ni #drag-handle slotida moslashtiring:
<template>
<VxTree :data="data" draggable>
<template #drag-handle="{ node }">
<MyGripIcon />
</template>
</VxTree>
</template>Lazy Loading
Bolalarni zarurat bo‘lganda yuklash uchun load funksiyasini uzating. Faqat ma’lumotingizni va loader’ni bering — qolganini daraxt o‘zi bajaradi:
- Yuklash paytida spinner ko‘rsatiladi
- Bo‘sh natija tugunni avtomatik barg (leaf) sifatida belgilaydi (qayta yuklashga urinmaydi)
- Xatoliklar inline tarzda Retry tugmasi bilan ko‘rsatiladi
- Oldin yuklangan tugunlar keshlanadi — qayta ochilganda qayta fetch qilinmaydi
- Sizga aniq bargligi ma’lum bo‘lgan tugunlarda yuklashni o‘tkazib yuborish uchun
isLeaf: true’dan foydalaning
Basic
Click the arrows to load children on demand. "Empty Folder" returns no results and becomes a leaf.
<script setup>
import { ref } from 'vue'
const data = ref([
{ key: 'folder-a', label: 'Folder A' },
{ key: 'folder-b', label: 'Folder B' },
{ key: 'empty', label: 'Empty Folder' },
{ key: 'readme', label: 'readme.txt', isLeaf: true },
])
async function load(node) {
const res = await fetch(`/api/${node.key}/children`)
return await res.json() // return TreeNodeData[]
}
</script>
<template>
<VxTree :data="data" :load="load" />
</template>Error Handling & Retry
Agar load xatolik tashlasa, daraxt qayta urinish tugmasi bilan xatolik xabarini ko‘rsatadi. Xato holatini ko‘rish uchun quyidagi "Orders"’ni bosing.
<script setup>
async function load(node) {
const res = await fetch(`/api/${node.key}/children`)
if (!res.ok) throw new Error('Failed to fetch')
return await res.json()
}
</script>
<template>
<!-- Errors show inline with a Retry button -->
<VxTree :data="data" :load="load" />
</template>Editable Labels
Inline qayta nomlashga ruxsat berish uchun editable’ni yoqing. Yozuvni tahrirlash uchun uni ikki marta bosing. Saqlash uchun Enter, bekor qilish uchun Escape bosing. O‘zgarishlarni qo‘llash uchun node-edit hodisasini qayta ishlang.
Double-click a label to rename it
<script setup>
function onEdit({ node, newLabel, oldLabel }) {
node.label = newLabel // apply the change
}
</script>
<template>
<VxTree :data="data" editable @node-edit="onEdit" />
</template>Context Menu
O‘ng tugma menyusini qo‘shish uchun #context-menu slotidan foydalaning. Slotga node va close uzatiladi.
Right-click any node to see the context menu
<template>
<VxTree :data="data">
<template #context-menu="{ node, close }">
<div class="menu">
<button @click="openNode(node); close()">Open</button>
<button @click="renameNode(node); close()">Rename</button>
<button @click="deleteNode(node); close()">Delete</button>
</div>
</template>
</VxTree>
</template>Striped Rows
O‘qishni osonlashtirish uchun almashinib turuvchi qator fonlarini qo‘shish uchun striped’ni qo‘shing.
<template>
<VxTree :data="data" striped default-expand-all />
</template>Virtual Scrolling
Katta ma’lumotlar to‘plami uchun faqat ko‘rinadigan tugunlarni renderlash maqsadida virtual’ni yoqing. Konteyner balandligi uchun virtual-height’ni va har bir qator uchun item-height’ni belgilang.
50 categories × 20 items = 1,000 nodes
<script setup>
// Generate 1,000 nodes
const data = Array.from({ length: 50 }, (_, i) => ({
key: `cat-${i}`,
label: `Category ${i + 1}`,
children: Array.from({ length: 20 }, (_, j) => ({
key: `cat-${i}-item-${j}`,
label: `Item ${i + 1}-${j + 1}`,
isLeaf: true,
})),
}))
</script>
<template>
<VxTree :data="data" virtual :virtual-height="300" :item-height="30" default-expand-all />
</template>Disabled Nodes
disabled: true bo‘lgan tugunlarni tanlash yoki belgilash mumkin emas.
Custom Content
Tugunni to‘liq maxsus tarzda renderlash uchun default slotdan foydalaning. U node, expanded, selected va checkState’ni qabul qiladi.
<template>
<VxTree :data="data" default-expand-all>
<template #default="{ node, expanded }">
<span>{{ node.children ? (expanded ? '📂' : '📁') : '📄' }} {{ node.label }}</span>
</template>
</VxTree>
</template>API
VxTree Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | TreeNodeData[] | [] | Daraxt ma’lumotlari |
selected | string | number | null | array | null | Tanlangan kalit(lar) (v-model) |
checked | (string | number)[] | [] | Belgilangan kalitlar (v-model) |
expanded | (string | number)[] | — | Ochilgan kalitlar (v-model) |
default-expand-all | boolean | false | Mount paytida hammasini ochish |
default-expanded-keys | (string | number)[] | [] | Mount paytida ochiladigan kalitlar |
checkable | boolean | false | Checkboxlarni ko‘rsatish |
selectable | boolean | true | Tanlovni yoqish |
multiple | boolean | false | Ko‘p tanlovga ruxsat (Ctrl/Cmd+Click) |
show-line | boolean | false | Ulovchi chiziqlarni ko‘rsatish |
line-style | 'solid' | 'dashed' | 'dotted' | 'solid' | Chiziq uslubi |
accordion | boolean | false | Har bir darajada faqat bitta tugun |
indent | number | 24 | Har bir daraja uchun chekinish (px) |
filter-text | string | '' | Yozuv bo‘yicha filtr |
highlight-filter | boolean | true | Mos kelgan filtr matnini ajratib ko‘rsatish |
draggable | boolean | false | Drag & drop’ni yoqish |
editable | boolean | false | Ikki marta bosib qayta nomlashni yoqish |
show-count | boolean | false | Bolalar soni badge’ini ko‘rsatish |
striped | boolean | false | Almashinib turuvchi qator fonlari |
load | (node) => Promise<TreeNodeData[]> | — | Asinxron bolalar yuklovchisi |
virtual | boolean | false | Virtual scrollni yoqish |
virtual-height | number | 400 | Virtual konteyner balandligi (px) |
item-height | number | 30 | Virtual element balandligi (px) |
TreeNodeData
| Property | Type | Required | Description |
|---|---|---|---|
key | string | number | Yes | Noyob identifikator |
label | string | Yes | Ko‘rsatiladigan matn |
children | TreeNodeData[] | No | Bolalar tugunlari |
disabled | boolean | No | Interaksiyani o‘chirib qo‘yish |
isLeaf | boolean | No | Majburiy barg (lazy load’ni o‘tkazib yuboradi) |
icon | string | No | Tugun ikoni (emoji yoki matn) |
Events
| Event | Payload | Description |
|---|---|---|
update:selected | key | keys[] | Tanlov o‘zgardi |
update:checked | keys[] | Belgilash holati o‘zgardi |
update:expanded | keys[] | Ochilish holati o‘zgardi |
node-click | node | Tugun bosildi |
node-expand | node | Tugun ochildi |
node-collapse | node | Tugun yopildi |
node-drop | { dragNode, dropNode, position } | Tugun tashlab yuborildi (drag & drop) |
node-drag-start | node | Sudrash boshlandi |
node-edit | { node, newLabel, oldLabel } | Yozuv tahrirlandi |
node-context-menu | { node, event } | Tugun ustida o‘ng tugma |
node-loaded | node, children | Lazy load tugadi |
Slots
| Slot | Props | Description |
|---|---|---|
default | { node, expanded, selected, checkState } | Maxsus tugun kontenti |
icon | { node, expanded } | Maxsus tugun ikoni |
actions | { node } | Hover paytidagi amal tugmalari |
drag-handle | { node } | Maxsus drag handle |
count | { node, count } | Maxsus count badge’i |
context-menu | { node, close } | O‘ng tugma konteks menyusi |
empty | — | Ma’lumot bo‘sh bo‘lganda ko‘rinadigan kontent |