js实现treeselect
以下是使用 JavaScript 实现 TreeSelect 组件的方法,结合递归渲染和事件处理:
数据结构设计
TreeSelect 需要一个树形结构的数据,通常每个节点包含 label、value 和 children 属性:
const treeData = [
{
label: "Parent 1",
value: "p1",
children: [
{ label: "Child 1", value: "c1" },
{ label: "Child 2", value: "c2" }
]
}
];
递归渲染树节点
使用递归函数渲染树形结构,支持展开/折叠:
function renderTreeNode(node, level = 0) {
return `
<div class="tree-node" style="padding-left: ${level * 20}px">
${node.children ?
`<span class="toggle">+</span>` :
`<span class="spacer"></span>`
}
<label>
<input type="checkbox" value="${node.value}">
${node.label}
</label>
${node.children ?
`<div class="children">${node.children.map(child =>
renderTreeNode(child, level + 1)).join('')}</div>` :
''
}
</div>
`;
}
事件处理
添加点击事件处理展开/折叠和选择:
document.addEventListener('click', (e) => {
// 处理展开/折叠
if (e.target.classList.contains('toggle')) {
const children = e.target.parentNode.querySelector('.children');
children.style.display = children.style.display === 'none' ? 'block' : 'none';
e.target.textContent = e.target.textContent === '+' ? '-' : '+';
}
// 处理复选框选择
if (e.target.matches('input[type="checkbox"]')) {
const checked = e.target.checked;
// 处理子节点全选/取消
if (e.target.closest('.tree-node').querySelector('.children')) {
e.target.closest('.tree-node')
.querySelectorAll('input[type="checkbox"]')
.forEach(checkbox => checkbox.checked = checked);
}
}
});
样式设计
基础 CSS 样式示例:
.tree-node {
padding: 5px 0;
cursor: pointer;
}
.toggle, .spacer {
display: inline-block;
width: 20px;
}
.children {
display: none;
}
.children.show {
display: block;
}
完整组件封装
将功能封装为可复用的类:

class TreeSelect {
constructor(container, data) {
this.container = document.querySelector(container);
this.data = data;
this.render();
}
render() {
this.container.innerHTML = this.data.map(node =>
renderTreeNode(node)).join('');
}
getSelectedValues() {
return Array.from(this.container.querySelectorAll('input:checked'))
.map(input => input.value);
}
}
// 使用示例
const treeSelect = new TreeSelect('#tree-container', treeData);
功能扩展建议
- 添加搜索过滤功能
- 支持异步加载子节点
- 实现多选/单选模式切换
- 添加自定义图标支持
这种方法实现了基本的 TreeSelect 功能,可以根据需求进一步扩展和完善交互细节。






