樹狀表格用於以表格格式顯示階層式資料。
import TreeTable from 'primevue/treetable';
import Column from 'primevue/column';
樹狀表格需要一個 TreeNode 實例的集合作為 value,以及 Column 元件作為表示的子元件。具有切換節點元素的欄位應啟用 expander。
<TreeTable :value="nodes" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
可以程式化地建立欄位。
<TreeTable :value="nodes" tableStyle="min-width: 50rem">
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header" :expander="col.expander"></Column>
</TreeTable>
展開狀態由 expandedKeys 屬性控制。expandedKeys 應該是一個物件,其鍵指向節點鍵,而值表示展開狀態,例如 {'0-0': true}。
<Button @click="toggleApplications" label="Toggle Applications" />
<TreeTable v-model:expandedKeys="expandedKeys" :value="nodes" class="mt-6" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
透過範本支援 header 和 footer 插槽的自訂內容。
<TreeTable :value="nodes" tableStyle="min-width: 50rem">
<template #header>
<div class="text-xl font-bold">File Viewer</div>
</template>
<Column field="name" header="Name" expander style="width: 250px"></Column>
<Column field="size" header="Size" style="width: 150px"></Column>
<Column field="type" header="Type" style="width: 150px"></Column>
<Column style="width: 10rem">
<template #body>
<div class="flex flex-wrap gap-2">
<Button type="button" icon="pi pi-search" rounded />
<Button type="button" icon="pi pi-pencil" rounded severity="success" />
</div>
</template>
</Column>
<template #footer>
<div class="flex justify-start">
<Button icon="pi pi-refresh" label="Reload" severity="warn" />
</div>
</template>
</TreeTable>
除了常規表格外,還有其他大小的替代方案。
<TreeTable :value="nodes" :size="size.value" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
透過新增 paginator 屬性並定義每頁的 rows 來啟用分頁。
<TreeTable :value="nodes" :paginator="true" :rows="5" :rowsPerPageOptions="[5, 10, 25]" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
使用 paginatorTemplate 屬性自訂分頁器 UI。每個元素也可以使用您自己的 UI 進一步自訂以取代預設的 UI,請參閱 分頁器 元件以取得有關進階自訂選項的更多資訊。
<TreeTable
:value="nodes"
:paginator="true"
:rows="5"
:rowsPerPageOptions="[5, 10, 25, 50]"
paginatorTemplate="RowsPerPageDropdown FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink"
currentPageReportTemplate="{first} to {last} of {totalRecords}"
tableStyle="min-width: 50rem"
>
<template #paginatorstart>
<Button type="button" icon="pi pi-refresh" text />
</template>
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
<template #paginatorend>
<Button type="button" icon="pi pi-download" text />
</template>
</TreeTable>
透過新增 paginator 屬性並定義每頁的 rows 來啟用分頁。
<TreeTable :value="nodes" :paginator="true" :rows="5" :rowsPerPageOptions="[5, 10, 25]" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
<template #paginatorcontainer="{ first, last, page, pageCount, prevPageCallback, nextPageCallback, totalRecords }">
<div class="flex items-center gap-4 border border-primary bg-transparent rounded-full w-full py-1 px-2 justify-between">
<Button icon="pi pi-chevron-left" rounded text @click="prevPageCallback" :disabled="page === 0" />
<div class="text-color font-medium">
<span class="hidden sm:block">Showing {{ first }} to {{ last }} of {{ totalRecords }}</span>
<span class="block sm:hidden">Page {{ page + 1 }} of {{ pageCount }}</span>
</div>
<Button icon="pi pi-chevron-right" rounded text @click="nextPageCallback" :disabled="page === pageCount - 1" />
</div>
</template>
</TreeTable>
透過新增 sortable 屬性來啟用欄位排序。
<TreeTable :value="nodes" tableStyle="min-width: 50rem">
<Column field="name" header="Name" sortable expander style="width: 34%"></Column>
<Column field="size" header="Size" sortable style="width: 33%"></Column>
<Column field="type" header="Type" sortable style="width: 33%"></Column>
</TreeTable>
可以透過將 sortMode 定義為 multiple 來對多個欄位進行排序。此模式需要按下 meta 鍵(例如 ⌘)才能點擊標頭。
<TreeTable :value="nodes" sortMode="multiple" tableStyle="min-width: 50rem">
<Column field="name" header="Name" sortable expander style="width: 34%"></Column>
<Column field="size" header="Size" sortable style="width: 33%"></Column>
<Column field="type" header="Type" sortable style="width: 33%"></Column>
</TreeTable>
當存在 removableSort 時,第三次點擊會從欄位中移除排序。
<TreeTable :value="nodes" sortMode="multiple" removableSort tableStyle="min-width: 50rem">
<Column field="name" header="Name" sortable expander style="width: 34%"></Column>
<Column field="size" header="Size" sortable style="width: 33%"></Column>
<Column field="type" header="Type" sortable style="width: 33%"></Column>
</TreeTable>
透過將 filter 屬性新增至欄位來啟用篩選。filterMode 指定篩選策略,在 lenient 模式下,當查詢符合節點時,不會進一步搜尋節點的子節點,因為該節點的所有子代都包含在內。另一方面,在 strict 模式下,當查詢符合節點時,會繼續篩選所有子代。還提供了一個名為 globalFilter 的通用填寫欄位,以搜尋所有支援篩選的欄位。
<SelectButton v-model="filterMode" optionLabel="label" dataKey="label" :options="filterOptions" />
<TreeTable :value="nodes" :filters="filters" :filterMode="filterMode.value">
<template #header>
<div class="flex justify-end">
<IconField>
<InputIcon class="pi pi-search" />
<InputText v-model="filters['global']" placeholder="Global Search" />
</IconField>
</div>
</template>
<Column field="name" header="Name" expander style="min-width: 12rem">
<template #filter>
<InputText v-model="filters['name']" type="text" placeholder="Filter by name" />
</template>
</Column>
<Column field="size" header="Size" style="min-width: 12rem">
<template #filter>
<InputText v-model="filters['size']" type="text" placeholder="Filter by size" />
</template>
</Column>
<Column field="type" header="Type" style="min-width: 12rem">
<template #filter>
<InputText v-model="filters['type']" type="text" placeholder="Filter by type" />
</template>
</Column>
</TreeTable>
單一節點選取透過將 selectionMode 設定為 single 以及 selectionKeys 屬性來管理選取值繫結進行配置。
預設情況下,需要按下 meta 鍵(例如 ⌘)才能取消選取節點,但是可以透過停用 metaKeySelection 屬性來設定此行為。在觸控式裝置中,此選項無效,且行為與將其設定為 false 相同。
<ToggleSwitch v-model="metaKey" inputId="input-metakey" />
<TreeTable v-model:selectionKeys="selectedKey" :value="nodes" selectionMode="single" :metaKeySelection="metaKey" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
透過將 selectionMode 設定為 multiple,可以選取多個節點。預設情況下,在多重選取模式下,不需要按下 meta 鍵(例如 ⌘)即可新增到現有選取範圍。當存在選用的 metaKeySelection 時,會以需要按下 meta 鍵才能選取新節點的方式變更行為。請注意,在觸控式裝置中,樹狀表格會始終忽略 meta 鍵。
在多重選取模式下,值繫結應為鍵值對,其中鍵是節點鍵,而值是布林值,用於指示選取。
<ToggleSwitch v-model="metaKey" inputId="input-metakey" />
<TreeTable v-model:selectionKeys="selectedKey" :value="nodes" selectionMode="multiple" :metaKeySelection="metaKey" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
透過將 selectionMode 配置為 checkbox,可以透過核取方塊選取多個節點。
在核取方塊選取模式下,值繫結應為鍵值對,其中鍵(或 dataKey)是節點鍵,而值是一個物件,該物件具有 checked 和 partialChecked 屬性,以表示節點的勾選狀態。
{
'0-0': {
partialChecked: false,
checked: true
}
}
<TreeTable v-model:selectionKeys="selectedKey" :value="nodes" selectionMode="checkbox" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
樹狀表格提供 nodeSelect 和 nodeUnselect 事件以偵聽選取事件。
<TreeTable v-model:selectionKeys="selectedKey" :value="nodes" selectionMode="single" @nodeSelect="onNodeSelect" @nodeUnselect="onNodeUnselect" :metaKeySelection="false" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
延遲模式對於處理大型資料集非常方便,而不是載入整個資料,而是每次發生 paging、sorting 和 filtering 時呼叫相應的回呼來載入小區塊的資料。以下範例使用記憶體清單和逾時來模擬網路連線,以模仿從遠端資料來源延遲載入資料。
啟用 lazy 屬性並透過執行投射查詢將邏輯列數指派給 totalRecords 是實作的關鍵要素,以便分頁器顯示 UI,假設實際存在 totalRecords 大小的記錄,儘管實際上它們不在頁面上,僅存在於目前頁面上顯示的記錄。
此外,只應載入根元素,可以使用 nodeExpand 回呼按需載入子元素。
<TreeTable :value="nodes" :lazy="true" :paginator="true" :rows="rows" :loading="loading"
@nodeExpand="onExpand" @page="onPage" :totalRecords="totalRecords" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
新增 scrollable 屬性以及資料檢視區的 scrollHeight 可以使用固定標頭啟用垂直滾動。
<TreeTable :value="nodes" scrollable scrollHeight="270px" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
彈性滾動功能使可滾動檢視區部分動態化,而不是固定值,因此它可以相對於表格的父系大小增大或縮小。按一下下面的按鈕以顯示可最大化的對話框,其中資料檢視區會根據大小變更自行調整。
<Button label="Show" icon="pi pi-external-link" @click="dialogVisible = true" />
<Dialog v-model:visible="dialogVisible" header="Flex Scroll" :style="{ width: '75vw' }" maximizable modal :contentStyle="{ height: '300px' }">
<TreeTable :value="nodes" :scrollable="true" scrollHeight="flex" tableStyle="min-width: 50rem">
<Column field="name" header="Name" :expander="true" style="min-width: 200px"></Column>
<Column field="size" header="Size" style="min-width: 200px"></Column>
<Column field="type" header="Type" style="min-width: 200px"></Column>
</TreeTable>
<template #footer>
<Button label="Ok" icon="pi pi-check" @click="dialogVisible = false" />
</template>
</Dialog>
當表格寬度超過父系寬度時,會顯示水平捲軸。
<TreeTable :value="nodes" scrollable scrollHeight="300px">
<Column field="name" header="Name" expander style="min-width: 250px"></Column>
<Column field="size" header="Size" style="min-width: 200px"></Column>
<Column field="type" header="Type 2" style="min-width: 200px"></Column>
<Column field="size" header="Size 2" style="min-width: 200px"></Column>
<Column field="type" header="Type 3" style="min-width: 200px"></Column>
<Column field="size" header="Size 3" style="min-width: 200px"></Column>
</TreeTable>
可以透過啟用欄位的 frozen 屬性在水平滾動期間固定欄位。位置透過 alignFrozen 定義,可以是 left 或 right。
<TreeTable :value="nodes" scrollable scrollHeight="300px">
<Column field="name" header="Name" expander frozen style="min-width: 250px" class="font-bold"></Column>
<Column field="size" header="Size" style="min-width: 200px"></Column>
<Column field="type" header="Type 2" style="min-width: 200px"></Column>
<Column field="size" header="Size 2" style="min-width: 200px"></Column>
<Column field="type" header="Type 3" style="min-width: 200px"></Column>
<Column field="size" header="Size 3" style="min-width: 200px"></Column>
</TreeTable>
啟用 resizableColumns 後,可以透過拖放來調整欄位大小。預設調整大小模式為 fit,不會變更表格的整體寬度。
<TreeTable :value="nodes" :resizableColumns="true" showGridlines tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
將 columnResizeMode 設定為 expand 也會變更表格寬度。
<TreeTable :value="nodes" :resizableColumns="true" columnResizeMode="expand" showGridlines tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
可以使用動態欄位實作基於條件的欄位可見性,在此範例中,多選下拉選單用於管理可見欄位。
<TreeTable :value="nodes" tableStyle="min-width: 50rem">
<template #header>
<div style="text-align:left">
<MultiSelect :modelValue="selectedColumns" @update:modelValue="onToggle" :options="columns" optionLabel="header" class="w-full sm:w-64" display="chip"/>
</div>
</template>
<Column field="name" header="Name" :expander="true"></Column>
<Column v-for="col of selectedColumns" :field="col.field" :header="col.header" :key="col.field"></Column>
</TreeTable>
樹狀表格透過 contextMenu 事件與上下文選單獨家整合,以在右鍵按一下時開啟選單,同時使用 contextMenuSelection 屬性和 row-contextmenu 事件來透過選單控制選取。
<ContextMenu ref="cm" :model="menuModel" @hide="selectedNode = null" />
<TreeTable v-model:contextMenuSelection="selectedNode" :value="nodes" contextMenu @row-contextmenu="onRowContextMenu" tableStyle="min-width: 50rem">
<Column field="name" header="Name" expander style="width: 34%"></Column>
<Column field="size" header="Size" style="width: 33%"></Column>
<Column field="type" header="Type" style="width: 33%"></Column>
</TreeTable>
資料表格使用 treegrid 元素,可以使用 tableProps 選項擴充其屬性。此屬性允許傳遞 aria 角色和屬性,例如 aria-label 和 aria-describedby,以定義讀取器的表格。表格的預設角色為 table。標頭、主體和頁尾元素使用 rowgroup,列使用 row 角色,標頭儲存格具有 columnheader,而主體儲存格使用 cell 角色。可排序的標頭利用 aria-sort 屬性設定為「升序」或「降序」。
列元素管理狀態的 aria-expanded 以及定義階層的 aria-posinset、aria-setsize 和 aria-level 屬性。
啟用選取時,會在列上將 aria-selected 設定為 true。在核取方塊模式下,樹狀表格元件會使用隱藏的原生核取方塊元素。
可編輯的儲存格使用自訂範本,因此如果需要,您需要手動管理 aria 角色和屬性。
分頁器是資料表格內部使用的獨立元件,請參閱 分頁器 以取得有關無障礙功能的更多資訊。
按鍵 | 功能 |
---|---|
tab | 在標頭之間移動。 |
enter | 排序欄位。 |
space | 排序欄位。 |
按鍵 | 功能 |
---|---|
tab | 當焦點進入元件時,如果有的話,會將焦點移至第一個選取的節點。如果沒有,則第一個元素會獲得焦點。如果焦點已經在元件內部,則會將焦點移至頁面 Tab 鍵順序中的下一個可聚焦元素。 |
Shift + Tab | 當焦點進入元件時,如果有的話,會將焦點移至最後一個選取的節點。如果沒有,則第一個元素會獲得焦點。如果焦點已經在元件內部,則會將焦點移至頁面 Tab 鍵順序中的上一個可聚焦元素。 |
enter | 選取焦點所在的樹狀節點。 |
space | 選取焦點所在的樹狀節點。 |
向下箭頭 | 將焦點移至下一個樹狀節點。 |
向上箭頭 | 將焦點移至上一個樹狀節點。 |
向右箭頭 | 如果節點是關閉的,則開啟節點;否則將焦點移至第一個子節點。 |
向左箭頭 | 如果節點是開啟的,則關閉節點;否則將焦點移至父節點。 |
Home | 將焦點移至第一個同級節點。 |
End | 將焦點移至最後一個同級節點。 |