当前位置:首页 > JavaScript

js实现无穷树形菜单

2026-03-01 16:40:17JavaScript

实现思路

使用递归组件实现无穷树形菜单,核心在于组件能够调用自身,并动态渲染子节点。数据结构通常采用嵌套的children数组形式。

数据结构示例

const treeData = [
  {
    id: 1,
    label: '节点1',
    children: [
      {
        id: 2,
        label: '节点1.1',
        children: [
          { id: 3, label: '节点1.1.1' }
        ]
      }
    ]
  },
  {
    id: 4,
    label: '节点2'
  }
]

递归组件实现

function TreeNode({ node }) {
  const [isExpanded, setIsExpanded] = useState(false)

  return (
    <div className="tree-node">
      <div 
        className="node-label" 
        onClick={() => setIsExpanded(!isExpanded)}
      >
        {node.children && (
          <span className="toggle-icon">
            {isExpanded ? '−' : '+'}
          </span>
        )}
        {node.label}
      </div>

      {isExpanded && node.children && (
        <div className="children">
          {node.children.map(child => (
            <TreeNode key={child.id} node={child} />
          ))}
        </div>
      )}
    </div>
  )
}

// 使用方式
function TreeMenu() {
  return (
    <div className="tree-menu">
      {treeData.map(node => (
        <TreeNode key={node.id} node={node} />
      ))}
    </div>
  )
}

样式建议

.tree-node {
  margin-left: 20px;
  cursor: pointer;
}

.node-label {
  padding: 5px;
}

.node-label:hover {
  background-color: #f0f0f0;
}

.toggle-icon {
  display: inline-block;
  width: 20px;
  text-align: center;
}

性能优化

对于大型树结构,可采用虚拟滚动技术。以下为简化版实现思路:

function useVirtualScroll(items, itemHeight, containerRef) {
  const [startIndex, setStartIndex] = useState(0)
  const visibleCount = Math.ceil(containerRef.current?.clientHeight / itemHeight)

  useEffect(() => {
    const handleScroll = () => {
      const newStart = Math.floor(containerRef.current.scrollTop / itemHeight)
      setStartIndex(newStart)
    }
    containerRef.current.addEventListener('scroll', handleScroll)
    return () => containerRef.current.removeEventListener('scroll', handleScroll)
  }, [])

  return items.slice(startIndex, startIndex + visibleCount)
}

动态加载方案

当数据量极大时,可采用懒加载方式:

async function loadChildren(parentId) {
  const response = await fetch(`/api/nodes?parent=${parentId}`)
  return response.json()
}

// 在TreeNode组件中
useEffect(() => {
  if (isExpanded && !node.children) {
    loadChildren(node.id).then(children => {
      // 更新数据逻辑
    })
  }
}, [isExpanded])

交互增强

添加复选框支持:

js实现无穷树形菜单

function TreeNode({ node, onCheck }) {
  const handleCheck = (e) => {
    e.stopPropagation()
    onCheck(node.id, e.target.checked)
  }

  return (
    <div className="tree-node">
      <input 
        type="checkbox" 
        checked={node.checked} 
        onChange={handleCheck}
      />
      {/* 其余代码 */}
    </div>
  )
}

注意事项

  1. 确保每个节点有唯一标识符(如id
  2. 深层嵌套时考虑使用不可变数据更新
  3. 对于超大数据量建议结合后端分页加载
  4. 可添加动画效果提升用户体验

标签: 菜单js
分享给朋友:

相关文章

vue实现菜单定位

vue实现菜单定位

实现菜单定位的方法 在Vue中实现菜单定位功能,可以通过监听滚动事件或使用Intersection Observer API来判断当前显示的菜单项,并高亮对应的导航链接。以下是几种常见的实现方式:…

css3结合js制作

css3结合js制作

CSS3 结合 JavaScript 制作动态效果 CSS3 和 JavaScript 结合可以实现丰富的动态效果,包括动画、交互和响应式设计。以下是几种常见的实现方式: CSS3 动画与 Java…

js实现轮播图

js实现轮播图

基础轮播图实现 使用HTML、CSS和JavaScript实现一个简单的自动轮播图。HTML结构包含一个容器和多个图片项。 <div class="slider"> <div…

jquery.js

jquery.js

jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互等操作。以下是关于 jQuery.js 的核心信息和使用方法: 获…

js实现瀑布流

js实现瀑布流

实现瀑布流布局 瀑布流布局是一种常见的网页布局方式,常用于图片展示、商品列表等场景。以下是使用 JavaScript 实现瀑布流布局的几种方法。 纯 JavaScript 实现 通过计算元素的位置和…

js实现防洪

js实现防洪

防抖(Debounce)实现 防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口调整等场景。 function debounce(func,…