## 概述

UserPicker 是一个功能强大的用户选择器组件，支持列表和树形两种显示模式。组件提供了搜索、多选、懒加载、自定义渲染等功能，适用于用户选择、组织架构选择、权限分配等业务场景。组件内置了选择状态管理、搜索过滤、树形展开等复杂逻辑，提供了简洁易用的 API 接口。

## Props 速查表

| 字段                   | 类型                                           | 默认值                        | 描述          |
| -------------------- | -------------------------------------------- | -------------------------- | ----------- |
| displayMode          | `'list' \| 'tree'`                           | 必填                         | 显示模式，列表或树形  |
| dataSource           | `UserPickerDataSource<T>`                    | `[]`                       | 数据源         |
| defaultSelectedItems | `Array<{ key: string; [key: string]: any }>` | `[]`                       | 默认选中项       |
| lockedItems          | `Array<{ key: string; [key: string]: any }>` | `[]`                       | 锁定项（不可取消选择） |
| maxCount             | `number`                                     | `Number.POSITIVE_INFINITY` | 最大选择数量      |
| minCount             | `number`                                     | `0`                        | 最小选择数量      |
| enableSearch         | `boolean`                                    | `true`                     | 是否启用搜索功能    |
| searchPlaceholder    | `string`                                     | `undefined`                | 搜索框占位符      |
| renderItem           | `Function`                                   | `undefined`                | 自定义渲染函数     |
| onSelectedChange     | `Function`                                   | `undefined`                | 选择变化回调      |
| onMaxCountExceed     | `Function`                                   | `undefined`                | 超出最大数量回调    |
| onSearch             | `Function`                                   | `undefined`                | 搜索回调        |
| onReachEnd           | `Function`                                   | `undefined`                | 列表模式滚动到底部回调 |
| onExpand             | `Function`                                   | `undefined`                | 树形模式展开回调    |

## Ref expose 方法速查表

|方法名	| 参数	| 返回值 | 描述 |
| -------- | ---- | ---- | ---- |
| getSelectedItems |	无	| UserPickerResult<T>	| 获取当前选中的项目 |
| updateTreeData |	nodeKey: string, partialNode: Partial<UserPickerNode<T>> | void	| 更新树形模式节点数据

## Props 详细介绍

### displayMode

- `类型`: `'list' | 'tree'`
- `描述`：组件的显示模式。`list` 模式显示平铺列表，`tree` 模式显示树形结构，支持层级展开和懒加载。

### dataSource

- `类型`: `UserPickerDataSource<T>`
- `描述`：组件的数据源，根据 displayMode 的不同接受不同的数据结构，默认值为 `[]`。

```typescript
// 列表模式数据结构
interface UserPickerRow<T = unknown> {
  key: string;           // 唯一标识符
  label: string;         // 显示名称
  avatarUrl?: string;    // 头像URL
  extraData?: T;         // 扩展数据
}

// 树形模式数据结构
interface UserPickerNode<T = unknown> {
  key: string;                        // 唯一标识符
  label: string;                      // 显示名称
  isLeafNode: boolean;                // 是否为叶子节点
  avatarUrl?: string;                 // 头像URL
  lazyLoad?: boolean;                 // 是否支持懒加载
  children?: Array<UserPickerNode<T>>; // 子节点
  extraData?: T;                      // 扩展数据
}

export type UserPickerDataSource<T = unknown> = Array<UserPickerRow<T>> | Array<UserPickerNode<T>>;
```

#### Example 1: 列表模式数据源

```vue
<template>
  <UserPicker
    display-mode="list"
    :data-source="listData"
    @selected-change="handleSelectionChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { UserPicker } from 'tuikit-atomicx-vue3';
import type { UserPickerRow } from 'tuikit-atomicx-vue3/types';

// 用户列表数据
const listData = ref<UserPickerRow[]>([
  {
    key: 'user1',
    label: '张三',
    avatarUrl: 'https://example.com/avatar1.jpg',
    extraData: { department: '技术部', role: '前端工程师' }
  },
  {
    key: 'user2',
    label: '李四',
    avatarUrl: 'https://example.com/avatar2.jpg',
    extraData: { department: '产品部', role: '产品经理' }
  }
]);

const handleSelectionChange = (selectedItems: any[]) => {
  console.log('选中的用户:', selectedItems);
};
</script>
```

### defaultSelectedItems

- `类型`: `Array<{ key: string; [key: string]: any }>`
- `描述`：默认选中的项目列表，通过 key 字段标识选中项，默认值为 `[]`。

### lockedItems

- `类型`: `Array<{ key: string; [key: string]: any }>`
- `描述`：锁定的项目列表，这些项目将被强制选中且用户无法取消选择，默认值为 `[]`。

### maxCount

- `类型`: `number`
- `描述`：允许选择的最大数量限制，超出时会触发 onMaxCountExceed 回调，默认值为 `Number.POSITIVE_INFINITY`。

### minCount

- `类型`: `number`
- `描述`：要求选择的最小数量，用于表单验证等场景，默认值为 `0`。

### enableSearch

- `类型`: `boolean`
- `描述`：是否启用搜索功能，启用后会显示搜索框，默认值为 `true`。

### searchPlaceholder

- `类型`: `string`
- `描述`：搜索框的占位符文本，如果不设置则使用默认的国际化文本，默认值为 `undefined`。

### renderItem

- `类型`: `(data: UserPickerRow<T> | UserPickerNode<T>) => any`
- `描述`：自定义项目渲染函数，可以自定义每个选项的显示内容和样式，默认值为 `undefined`。

```typescript
type RenderItemFunction<T> = (data: UserPickerRow<T> | UserPickerNode<T>) => VNode | string;
```

#### Example: 自定义渲染函数

```vue
<template>
  <UserPicker
    display-mode="list"
    :data-source="userData"
    :render-item="customRenderItem"
  />
</template>

<script setup lang="ts">
import { h } from 'vue';
import { UserPicker } from 'tuikit-atomicx-vue3';
import type { UserPickerRow } from 'tuikit-atomicx-vue3/types';

const userData = ref<UserPickerRow[]>([
  {
    key: 'user1',
    label: '张三',
    extraData: { status: 'online', department: '技术部' }
  }
]);

// 自定义渲染函数，显示用户状态和部门信息
const customRenderItem = (data: UserPickerRow) => {
  return h('div', { class: 'custom-user-item' }, [
    h('div', { class: 'user-name' }, data.label),
    h('div', { class: 'user-info' }, [
      h('span', {
        class: `status ${data.extraData?.status}`
      }, data.extraData?.status === 'online' ? '在线' : '离线'),
      h('span', { class: 'department' }, data.extraData?.department)
    ])
  ]);
};
</script>
```

### onSelectedChange

- `类型`: `(selectedItems: UserPickerResult<T>) => void`
- `描述`：选择状态变化时的回调函数，会传入当前选中的所有项目，默认值为 `undefined`。应该尽量减少使用避免频繁的触发回调函数。

```typescript
interface UserPickerResultItem<T = unknown> {
  key: string;
  label: string;
  avatarUrl?: string;
  isLeafNode?: boolean;    // 仅树形模式有意义
  extraData?: T;
  path?: string[];         // 仅树形模式有意义，记录节点路径
}

type UserPickerResult<T = unknown> = Array<UserPickerResultItem<T>>;
```

### onMaxCountExceed

- `类型`: `(selectedItems: UserPickerResult<T>) => void`
- `描述`：当选择数量超出 maxCount 限制时触发的回调函数，默认值为 `undefined`。

### onSearch

- `类型`: `(value: string) => void`
- `描述`：搜索输入变化时的回调函数，可用于实现服务端搜索，默认值为 `undefined`。

### onReachEnd

- `类型`: `() => void`
- `描述`：列表模式下滚动到底部时的回调函数，常用于实现分页加载，默认值为 `undefined`。

### onExpand

- `类型`: `(node: UserPickerNode<T>) => void`
- `描述`：树形模式下节点展开时的回调函数，用于实现懒加载子节点，默认值为 `undefined`。

## Ref Expose 方法详细介绍

### getSelectedItems

- `类型`：`() => UserPickerResult<T>`
- `描述`：作为选择完成后确认时的最佳实践。

```typescript
interface UserPickerResultItem<T = unknown> {
  key: string;
  label: string;
  avatarUrl?: string;
  isLeafNode?: boolean;    // 仅树形模式有意义
  extraData?: T;
  path?: string[];         // 仅树形模式有意义，记录节点路径
}

type UserPickerResult<T = unknown> = Array<UserPickerResultItem<T>>;
```

#### Example: 选择完成后确认时获取选中的项

```vue
<template>
  <UserPicker
    ref="userPickerRef"
    display-mode="list"
    :data-source="userData"
  />
</template>

<script setup lang="ts">
const userPickerRef = useRef();

function onConfirm() {
  userPickerRef.value.getSelectedItems();
}
