@hjxz/pharos-tree-select
v0.0.72
Published
hjxz 树级选择组件
Keywords
Readme
Pharos Tree Select
树级选择组件,支持无限层级数据渲染,父节点含子节点时显示展开/折叠图标,子节点继承父节点缩进样式。
特性
- 🌳 支持无限层级树形数据
- 🔽 展开/折叠功能(仅在有子节点时显示)
- 📏 可配置缩进距离(默认 16px)
- ✅ 支持单选/多选模式
- 🎨 现代化 UI 设计
- 📱 响应式布局
- ⚡ 虚拟滚动支持(大数据量优化)
- 🔍 集成搜索功能(搜索框在显示框中)
- 🎛️ 可配置字段映射
- 🎯 智能回显和搜索切换
安装
npm install @hjxz/pharos-tree-select使用
基础用法
<template>
<PharosTreeSelect
v-model:value="selectedValue"
:treeData="treeData"
:indent="20"
:multiple="true"
placeholder="请选择"
/>
</template>
<script setup>
import { ref } from 'vue'
import { PharosTreeSelect } from '@hjxz/pharos-tree-select'
const selectedValue = ref([])
const treeData = ref([
{
id: '1',
label: '一级节点',
children: [
{
id: '1-1',
label: '二级节点 1',
children: [
{ id: '1-1-1', label: '三级节点 1' },
{ id: '1-1-2', label: '三级节点 2' }
]
},
{ id: '1-2', label: '二级节点 2' }
]
}
])
</script>虚拟滚动(大数据量)
<template>
<PharosTreeSelect
v-model:value="selectedValue"
:treeData="largeTreeData"
:virtual-scroll="true"
:item-height="32"
:visible-count="10"
placeholder="请选择(虚拟滚动)"
/>
</template>
<script setup>
import { ref } from 'vue'
import { PharosTreeSelect } from '@hjxz/pharos-tree-select'
const selectedValue = ref('')
const largeTreeData = ref([
// 大量数据,建议 1000+ 节点时使用虚拟滚动
])
</script>多选 + 虚拟滚动
<template>
<PharosTreeSelect
v-model:value="selectedValues"
:treeData="largeTreeData"
:multiple="true"
:virtual-scroll="true"
:item-height="32"
:visible-count="8"
placeholder="请选择多个节点"
/>
</template>
<script setup>
import { ref } from 'vue'
import { PharosTreeSelect } from '@hjxz/pharos-tree-select'
const selectedValues = ref([])
const largeTreeData = ref([
// 大量数据
])
</script>集成搜索功能
<template>
<!-- 基础搜索 -->
<PharosTreeSelect
v-model:value="selectedValue"
:treeData="treeData"
:show-search="true"
search-placeholder="请输入搜索关键词"
placeholder="请选择节点"
/>
<!-- 自定义搜索过滤 -->
<PharosTreeSelect
v-model:value="selectedValue"
:treeData="treeData"
:show-search="true"
:filter-option="customFilter"
search-placeholder="自定义搜索"
placeholder="请选择节点"
/>
<!-- 禁用搜索 -->
<PharosTreeSelect
v-model:value="selectedValue"
:treeData="treeData"
:show-search="false"
placeholder="请选择节点(无搜索)"
/>
</template>
<script setup>
import { ref } from 'vue'
import { PharosTreeSelect } from '@hjxz/pharos-tree-select'
const selectedValue = ref('')
const treeData = ref([
// 树形数据
])
// 自定义过滤函数
const customFilter = (input: string, option: TreeNode): boolean => {
return option.label?.toString().toLowerCase().includes(input.toLowerCase()) || false
}
</script>API
Props
| 参数 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| value / v-model:value | 绑定值 | string \| string[] | - |
| treeData | 树形数据 | TreeNode[] | [] |
| multiple | 是否多选 | boolean | false |
| indent | 缩进距离(px) | number | 16 |
| placeholder | 占位符 | string | '请选择' |
| disabled | 是否禁用 | boolean | false |
| checkable | 是否显示复选框 | boolean | false |
| fieldNames | 字段映射配置 | TreeFieldNames | { id: 'id', label: 'label', children: 'children', disabled: 'disabled', isLeaf: 'isLeaf', extra: 'extra' } |
| searchValue | 搜索值 | string | - |
| showSearch | 是否显示搜索功能 | boolean | true |
| searchPlaceholder | 搜索框占位符 | string | '搜索' |
| filterOption | 自定义搜索过滤函数 | (input: string, option: TreeNode) => boolean | - |
| virtualScroll | 是否启用虚拟滚动 | boolean | false |
| itemHeight | 虚拟滚动项目高度(px) | number | 32 |
| visibleCount | 虚拟滚动可见项目数量 | number | 10 |
| api | 数据请求接口 | function | |
Events
| 事件名 | 说明 | 回调参数 |
|--------|------|----------|
| change | 选择变化时触发 | (value: string \| string[]) |
| expand | 节点展开/折叠时触发 | (expandedKeys: string[], { expanded: boolean, node: TreeNode }) |
| selectChange | 选择变化时触发 | (value: string \| string[]) |
| nodeExpand | 节点展开/折叠时触发 | (node: TreeNode, expanded: boolean) |
| load | 节点懒加载时触发 | (node: TreeNode) |
| search | 搜索时触发 | (keyword: string) |
| clear | 清空时触发 | (value: string \| string[]) |
| dropdownChange | 下拉框显示/隐藏时触发 | (visible: boolean) |
TreeNode
| 属性 | 说明 | 类型 | 必填 |
|------|------|------|------|
| id | 节点唯一标识 | string | ✅ |
| label | 节点显示文本 | string | ✅ |
| children | 子节点 | TreeNode[] | ❌ |
| disabled | 是否禁用 | boolean | ❌ |
| isLeaf | 是否为叶子节点 | boolean | ❌ |
| extra | 额外数据 | any | ❌ |
TreeFieldNames
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| id | 节点唯一标识字段名 | string | 'id' |
| label | 节点显示文本字段名 | string | 'label' |
| children | 子节点字段名 | string | 'children' |
| disabled | 禁用状态字段名 | string | 'disabled' |
| isLeaf | 叶子节点字段名 | string | 'isLeaf' |
| extra | 额外数据字段名 | string | 'extra' |
虚拟滚动
当数据量较大(建议 1000+ 节点)时,可以启用虚拟滚动来优化性能:
性能优化
- 渲染优化: 只渲染可见区域的节点,大幅减少 DOM 节点数量
- 内存优化: 减少内存占用,提高页面响应速度
- 滚动流畅: 保持流畅的滚动体验
配置参数
virtualScroll: 是否启用虚拟滚动itemHeight: 每个节点的高度(px),用于计算滚动位置visibleCount: 可见区域显示的节点数量,影响容器高度
使用建议
- 数据量: 建议在 1000+ 节点时启用虚拟滚动
- 高度设置:
itemHeight应与实际节点高度一致 - 可见数量:
visibleCount建议设置为 8-15 之间 - 性能测试: 在目标设备上测试滚动性能
注意事项
- 虚拟滚动模式下,节点高度必须固定
- 搜索功能在虚拟滚动模式下仍然可用
- 展开/折叠功能完全兼容虚拟滚动
集成搜索功能
搜索功能已集成到组件的显示框中,提供更好的用户体验:
功能特性
- 智能切换: 点击显示框时自动进入搜索模式
- 回显功能: 显示已选中的内容,支持多选回显
- 实时搜索: 输入时实时过滤树形数据
- 自定义过滤: 支持自定义搜索过滤逻辑
- 键盘支持: 支持 ESC 键退出搜索模式
搜索模式
- 显示模式: 显示已选中的内容或占位符
- 搜索模式: 点击后进入搜索状态,显示搜索框
- 自动切换: 选择选项后自动退出搜索模式
自定义搜索
// 自定义过滤函数
const customFilter = (input: string, option: TreeNode): boolean => {
// 支持拼音搜索
const pinyinMap = {
'beijing': '北京',
'shanghai': '上海'
}
// 检查拼音匹配
for (const [pinyin, chinese] of Object.entries(pinyinMap)) {
if (pinyin.includes(input.toLowerCase()) &&
option.label?.includes(chinese)) {
return true
}
}
// 默认文本匹配
return option.label?.toLowerCase().includes(input.toLowerCase()) || false
}使用建议
- 搜索占位符: 设置清晰的搜索提示文本
- 过滤函数: 根据业务需求自定义搜索逻辑
- 性能优化: 大数据量时建议结合虚拟滚动使用
- 用户体验: 保持搜索框的响应性和流畅性
