跳转到内容

TreeSelect 树选择

用于分层数据的下拉树选择。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'

基础树选择

从树结构中选择单个值。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'
import { useState } from 'react'

function App() {
  const basicTreeData: TreeDataNode[] = [
    {
      key: 'parent',
      title: 'Parent Node',
      children: [
        {
          key: 'child1',
          title: 'Child Node 1',
          children: [
            { key: 'leaf1', title: 'Leaf 1' },
            { key: 'leaf2', title: 'Leaf 2' },
          ],
        },
        { key: 'child2', title: 'Child Node 2' },
      ],
    },
  ]
  
  const [value, setValue] = useState<string | undefined>()
  
  return (
      <TreeSelect
        treeData={basicTreeData}
        value={value}
        onChange={(val) => setValue(val as string)}
        placeholder="Select an item"
      />
    )
}

export default App

多选

从树中选择多个值。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'
import { useState } from 'react'

function App() {
  const categoriesData: TreeDataNode[] = [
    {
      key: 'electronics',
      title: 'Electronics',
      children: [
        {
          key: 'phones',
          title: 'Phones',
          children: [
            { key: 'iphone', title: 'iPhone' },
            { key: 'samsung', title: 'Samsung' },
            { key: 'pixel', title: 'Pixel' },
          ],
        },
        {
          key: 'laptops',
          title: 'Laptops',
          children: [
            { key: 'macbook', title: 'MacBook' },
            { key: 'thinkpad', title: 'ThinkPad' },
          ],
        },
      ],
    },
    {
      key: 'clothing',
      title: 'Clothing',
      children: [
        { key: 'shirts', title: 'Shirts' },
        { key: 'pants', title: 'Pants' },
        { key: 'shoes', title: 'Shoes' },
      ],
    },
  ]
  
  const [value, setValue] = useState<string[]>([])
  
  return (
      <TreeSelect
        treeData={categoriesData}
        value={value}
        onChange={(val) => setValue(val as string[])}
        placeholder="Select items"
        multiple
      />
    )
}

export default App

可勾选

使用复选框进行选择,带有父子关联。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'
import { useState } from 'react'

function App() {
  const categoriesData: TreeDataNode[] = [
    {
      key: 'electronics',
      title: 'Electronics',
      children: [
        {
          key: 'phones',
          title: 'Phones',
          children: [
            { key: 'iphone', title: 'iPhone' },
            { key: 'samsung', title: 'Samsung' },
            { key: 'pixel', title: 'Pixel' },
          ],
        },
        {
          key: 'laptops',
          title: 'Laptops',
          children: [
            { key: 'macbook', title: 'MacBook' },
            { key: 'thinkpad', title: 'ThinkPad' },
          ],
        },
      ],
    },
    {
      key: 'clothing',
      title: 'Clothing',
      children: [
        { key: 'shirts', title: 'Shirts' },
        { key: 'pants', title: 'Pants' },
        { key: 'shoes', title: 'Shoes' },
      ],
    },
  ]
  
  const [value, setValue] = useState<string[]>([])
  
  return (
      <TreeSelect
        treeData={categoriesData}
        value={value}
        onChange={(val) => setValue(val as string[])}
        placeholder="Check items"
        treeCheckable
      />
    )
}

export default App

可搜索

使用搜索过滤树节点。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'
import { useState } from 'react'

function App() {
  const categoriesData: TreeDataNode[] = [
    {
      key: 'electronics',
      title: 'Electronics',
      children: [
        {
          key: 'phones',
          title: 'Phones',
          children: [
            { key: 'iphone', title: 'iPhone' },
            { key: 'samsung', title: 'Samsung' },
            { key: 'pixel', title: 'Pixel' },
          ],
        },
        {
          key: 'laptops',
          title: 'Laptops',
          children: [
            { key: 'macbook', title: 'MacBook' },
            { key: 'thinkpad', title: 'ThinkPad' },
          ],
        },
      ],
    },
    {
      key: 'clothing',
      title: 'Clothing',
      children: [
        { key: 'shirts', title: 'Shirts' },
        { key: 'pants', title: 'Pants' },
        { key: 'shoes', title: 'Shoes' },
      ],
    },
  ]
  
  const [value, setValue] = useState<string | undefined>()
  
  return (
      <TreeSelect
        treeData={categoriesData}
        value={value}
        onChange={(val) => setValue(val as string)}
        placeholder="Search and select"
        showSearch
      />
    )
}

export default App

尺寸

TreeSelect 有各种尺寸。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'

function App() {
  const simpleData: TreeDataNode[] = [
    { key: 'opt1', title: 'Option 1' },
    { key: 'opt2', title: 'Option 2' },
    { key: 'opt3', title: 'Option 3' },
  ]
  
  return (
      <div className="flex flex-col gap-2">
        <TreeSelect treeData={simpleData} size="xs" placeholder="Extra small" />
        <TreeSelect treeData={simpleData} size="sm" placeholder="Small" />
        <TreeSelect treeData={simpleData} size="md" placeholder="Medium" />
        <TreeSelect treeData={simpleData} size="lg" placeholder="Large" />
        <TreeSelect treeData={simpleData} size="xl" placeholder="Extra large" />
      </div>
    )
}

export default App

验证状态

显示错误或警告状态。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'

function App() {
  const simpleData: TreeDataNode[] = [
    { key: 'opt1', title: 'Option 1' },
    { key: 'opt2', title: 'Option 2' },
    { key: 'opt3', title: 'Option 3' },
  ]
  
  return (
      <div className="flex flex-col gap-2">
        <TreeSelect treeData={simpleData} status="error" placeholder="Error state" />
        <TreeSelect treeData={simpleData} status="warning" placeholder="Warning state" />
      </div>
    )
}

export default App

异步加载

展开时异步加载树节点。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'
import { useState } from 'react'

function App() {
  const [treeData, setTreeData] = useState<TreeDataNode[]>([
    { key: 'region1', title: 'Region 1' },
    { key: 'region2', title: 'Region 2' },
  ])
  
  const loadData = async (node: TreeDataNode) => {
    await new Promise((resolve) => setTimeout(resolve, 1000))
    setTreeData((prev) => {
      const updateNode = (nodes: TreeDataNode[]): TreeDataNode[] =>
        nodes.map((n) =>
          n.key === node.key
            ? {
                ...n,
                children: [
                  { key: `${n.key}-1`, title: 'Child 1', isLeaf: true },
                  { key: `${n.key}-2`, title: 'Child 2', isLeaf: true },
                ],
              }
            : { ...n, children: n.children ? updateNode(n.children) : undefined }
        )
      return updateNode(prev)
    })
  }
  
  return (
      <TreeSelect
        treeData={treeData}
        loadData={loadData}
        placeholder="Expand to load"
      />
    )
}

export default App

最大标签数

限制可见标签的数量。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'
import { useState } from 'react'

function App() {
  const categoriesData: TreeDataNode[] = [
    {
      key: 'electronics',
      title: 'Electronics',
      children: [
        {
          key: 'phones',
          title: 'Phones',
          children: [
            { key: 'iphone', title: 'iPhone' },
            { key: 'samsung', title: 'Samsung' },
            { key: 'pixel', title: 'Pixel' },
          ],
        },
        {
          key: 'laptops',
          title: 'Laptops',
          children: [
            { key: 'macbook', title: 'MacBook' },
            { key: 'thinkpad', title: 'ThinkPad' },
          ],
        },
      ],
    },
    {
      key: 'clothing',
      title: 'Clothing',
      children: [
        { key: 'shirts', title: 'Shirts' },
        { key: 'pants', title: 'Pants' },
        { key: 'shoes', title: 'Shoes' },
      ],
    },
  ]
  
  const [value, setValue] = useState<string[]>([])
  
  return (
      <TreeSelect
        treeData={categoriesData}
        value={value}
        onChange={(val) => setValue(val as string[])}
        placeholder="Select items"
        treeCheckable
        maxTagCount={2}
        maxTagPlaceholder={(omitted) => `+${omitted.length} more...`}
      />
    )
}

export default App

树连接线

显示树节点之间的连接线。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'

function App() {
  const basicTreeData: TreeDataNode[] = [
    {
      key: 'parent',
      title: 'Parent Node',
      children: [
        {
          key: 'child1',
          title: 'Child Node 1',
          children: [
            { key: 'leaf1', title: 'Leaf 1' },
            { key: 'leaf2', title: 'Leaf 2' },
          ],
        },
        { key: 'child2', title: 'Child Node 2' },
      ],
    },
  ]
  
  return (
      <TreeSelect
        treeData={basicTreeData}
        placeholder="With tree lines"
        treeLine
        treeDefaultExpandAll
      />
    )
}

export default App

禁用项目

某些树节点可以被禁用。

import { TreeSelect } from 'asterui'
import type { TreeDataNode } from 'asterui'
import { useState } from 'react'

function App() {
  const [value, setValue] = useState<string | undefined>()
  
  const treeDataWithDisabled: TreeDataNode[] = [
    {
      key: 'parent',
      title: 'Available Parent',
      children: [
        { key: 'child1', title: 'Available Child' },
        { key: 'child2', title: 'Disabled Child', disabled: true },
        { key: 'child3', title: 'Another Available' },
      ],
    },
  ]
  
  return (
      <TreeSelect
        treeData={treeDataWithDisabled}
        value={value}
        onChange={(val) => setValue(val as string)}
        placeholder="Select an item"
      />
    )
}

export default App
属性描述类型默认值
treeData树数据结构TreeDataNode[][]
value选定的值string | string[]-
defaultValue默认选定的值string | string[][]
onChange选择更改时的回调(value: string | string[], labels: ReactNode[]) => void-
multiple允许多选booleanfalse
treeCheckable显示树节点的复选框booleanfalse
treeCheckStrictly无父子关联地勾选booleanfalse
showCheckedStrategy如何显示已勾选项目'SHOW_ALL' | 'SHOW_PARENT' | 'SHOW_CHILD''SHOW_ALL'
showSearch启用搜索功能booleanfalse
searchValue受控搜索输入值string-
onSearch搜索输入更改时的回调(value: string) => void-
filterTreeNode自定义过滤函数(searchValue: string, node: TreeDataNode) => boolean-
placeholder占位符文本string'Please select'
allowClear显示清除按钮booleantrue
disabled禁用选择booleanfalse
size输入的大小'xs' | 'sm' | 'md' | 'lg' | 'xl''md'
color颜色主题'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'-
status验证状态'error' | 'warning'-
maxTagCount要显示的最大标签数number | 'responsive'-
maxTagPlaceholder隐藏标签的内容ReactNode | ((omittedValues: string[]) => ReactNode)-
treeLine显示连接线booleanfalse
treeDefaultExpandAll默认展开所有树节点booleanfalse
treeDefaultExpandedKeys默认展开的树节点键string[][]
treeExpandedKeys受控的已展开树节点键string[]-
onTreeExpand树节点展开/折叠时的回调(expandedKeys: string[]) => void-
loadData异步加载数据(node: TreeDataNode) => Promise<void>-
fieldNames自定义字段名称{ label?: string; value?: string; children?: string }-
open受控的下拉菜单可见性boolean-
onDropdownVisibleChange下拉菜单可见性更改时的回调(open: boolean) => void-
suffixIcon自定义后缀图标ReactNode-
switcherIcon自定义展开/折叠图标ReactNode | ((props: { expanded: boolean }) => ReactNode)-
notFoundContent无结果时的内容ReactNode'No results found'
dropdownRender自定义下拉内容渲染器(menu: ReactNode) => ReactNode-
popupClassName下拉菜单的类string-
data-testid组件的测试 IDstring'treeselect'
className额外的 CSS 类string-

TreeSelect 组件遵循 WAI-ARIA 组合框和树模式,具有正确的 ARIA 属性和键盘导航。

操作
Enter / Space打开下拉菜单或选择聚焦的项目
Escape关闭下拉菜单
打开下拉菜单或向下移动焦点
向上移动焦点
展开聚焦的树节点
折叠聚焦的树节点或移至父节点
Home将焦点移至第一个项目
End将焦点移至最后一个项目