Admin 元件

Tree

參考API
巢狀資料。展開、收合、選取。

安裝

Terminal
pnpm dlx shadcn-vue add @admin/tree
import { AdminTree, AdminTreeItem } from '@/components/admin/tree'

用法

<script setup lang="ts">import { ref } from 'vue'import { AdminTree, AdminTreeItem } from '@/components/admin/tree'​interface Node {  id: string  label: string  children?: Node[]}​const items: Node[] = [  {    id: '1',    label: '標題名稱',    children: [      { id: '1-1', label: '項目名稱' },      { id: '1-2', label: '項目名稱' },      {        id: '1-3',        label: '標題名稱',        children: [          { id: '1-3-1', label: '項目名稱' },          { id: '1-3-2', label: '項目名稱' },          {            id: '1-3-3',            label: '標題名稱',            children: [              { id: '1-3-3-1', label: '項目名稱' },              { id: '1-3-3-2', label: '項目名稱' },              {                id: '1-3-3-3',                label: '標題名稱',                children: [{ id: '1-3-3-3-1', label: '項目名稱' }]              }            ]          }        ]      }    ]  }]​const expanded = ref<string[]>(['1', '1-3', '1-3-3'])const selected = ref<Node | undefined>()</script>​<template>  <admin-tree    v-model="selected"    v-model:expanded="expanded"    class="w-[18rem] border border-text-30"    :get-key="(node: Node) => node.id"    :items  >    <template #default="{ flattenItems }">      <admin-tree-item        v-for="item in flattenItems"        :key="item._id"        v-bind="item.bind"        :has-children="item.hasChildren"      >        {{ item.value.label }}      </admin-tree-item>    </template>  </admin-tree></template>

場景

多選與 Checkbox

<script setup lang="ts">import { IconCaretDownFilled, IconCaretRightFilled } from '@tabler/icons-vue'import { ref } from 'vue'import { AdminCheckbox, AdminCheckboxInput } from '@/components/admin/checkbox'import { AdminTree, AdminTreeItem } from '@/components/admin/tree'​interface Node {  id: string  label: string  children?: Node[]}​const items: Node[] = [  {    id: 'a',    label: '標題名稱',    children: [      { id: 'a-1', label: '項目名稱' },      { id: 'a-2', label: '項目名稱' }    ]  },  {    id: 'b',    label: '標題名稱',    children: [      { id: 'b-1', label: '項目名稱' },      { id: 'b-2', label: '項目名稱' },      {        id: 'b-3',        label: '標題名稱',        children: [          { id: 'b-3-1', label: '項目名稱' },          { id: 'b-3-2', label: '項目名稱' }        ]      }    ]  }]​const expanded = ref<string[]>(['a', 'b', 'b-3'])const selected = ref<Node[]>([])</script>​<template>  <admin-tree    v-model="selected"    v-model:expanded="expanded"    class="w-[18rem] border border-text-30"    bubble-select    multiple    propagate-select    :get-key="(node: Node) => node.id"    :items  >    <template #default="{ flattenItems }">      <admin-tree-item        v-for="item in flattenItems"        :key="item._id"        v-bind="item.bind"        :has-children="item.hasChildren"        @select="(ev) => item.hasChildren && ev.preventDefault()"      >        <template #prefix="{ isSelected, isIndeterminate, isExpanded, hasChildren, handleSelect }">          <admin-checkbox class="shrink-0 cursor-pointer" @click.stop="handleSelect()">            <admin-checkbox-input              class="pointer-events-none"              tabindex="-1"              :model-value="isIndeterminate ? 'indeterminate' : isSelected"            />          </admin-checkbox>          <icon-caret-down-filled            v-if="hasChildren && isExpanded"            class="size-4 shrink-0 text-text-90"          />          <icon-caret-right-filled v-else-if="hasChildren" class="size-4 shrink-0 text-text-90" />        </template>        {{ item.value.label }}      </admin-tree-item>    </template>  </admin-tree></template>

API 參考

組成

<template>  <admin-tree v-slot="{ flattenItems }" :get-key="(item) => item.id" :items="data">    <admin-tree-item      v-for="item in flattenItems"      :key="item._id"      v-bind="item.bind"      :has-children="item.hasChildren"    >      {{ item.value.label }}    </admin-tree-item>  </admin-tree></template>

admin-tree

Props

名稱型別預設值說明
classClassValue—根元素之自訂 class
modelValue(Multiple extends true ? TValue[] : TValue) | undefined—The controlled value of the tree. Can be binded with `v-model`.
defaultValue(Multiple extends true ? TValue[] : TValue) | undefined—The value of the tree when initially rendered. Use when you do not need to control the state of the tree
itemsTItem[] | undefined—List of items
expandedstring[] | undefined—The controlled value of the expanded item. Can be binded with `v-model`.
defaultExpandedstring[] | undefined—The value of the expanded tree when initially rendered. Use when you do not need to control the state of the expanded tree
getKey*(val: TItem) => string—This function is passed the index of each item and should return a unique key for that item
getChildren((val: TItem) => TItem[] | undefined) | undefined—This function is passed the index of each item and should return a list of children for that item
selectionBehavior"toggle" | "replace" | undefined—How multiple selection should behave in the collection.
multipleboolean | Multiple | undefined—Whether multiple options can be selected or not.
dirDirection | undefined—The reading direction of the listbox when applicable. If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode.
disabledboolean | undefined—When `true`, prevents the user from interacting with tree
propagateSelectboolean | undefined—When `true`, selecting parent will select the descendants. Requires `multiple` to be `true`.
bubbleSelectboolean | undefined—When `true`, selecting children will update the parent state. Requires `multiple` to be `true`.
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.

* 代表必填

Events

名稱Payload說明
update:modelValueMultiple extends true ? TValue[] : TValue—
update:expandedstring[]—

Slots

名稱Bindings說明
default{ flattenItems: FlattenedItem<TItem>[]; modelValue: Multiple extends true ? TValue[] : TValue; expanded: string[]; }預設 slot,提供樹狀資料展開後之 flattened items、當前 modelValue 與展開狀態

admin-tree-item

Props

名稱型別預設值說明
classClassValue—根元素之自訂 class
value*TItem—Value given to this item
level*number—Level of depth
disabledboolean | undefined—When `true`, prevents the user from interacting with the item.
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
hasChildrenboolean | undefined—設為 `true` 時顯示展開/收合 caret icon

* 代表必填

Events

名稱Payload說明
selectSelectEvent<TItem>—
toggleToggleEvent<TItem>—

Slots

名稱Bindings說明
default{ isExpanded: boolean; isSelected: boolean; isIndeterminate: boolean | undefined; }預設 slot,提供節點互動狀態
prefix{ isExpanded: boolean; isSelected: boolean; isIndeterminate: boolean | undefined; hasChildren: boolean | undefined; handleToggle: () => void; handleSelect: () => void; }節點前綴 slot(預設渲染展開 caret),可覆蓋自訂

更新紀錄

  • fix: 補上 Vue 核心 API 的顯式 import3c2c030
  • feat: 對齊 admin-tree slot model 泛型65f7aec