当前位置:首页 > 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])

交互增强

添加复选框支持:

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实现无穷树形菜单

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

相关文章

vue菜单tab实现

vue菜单tab实现

实现Vue菜单Tab的步骤 在Vue中实现菜单Tab功能,可以通过动态组件或条件渲染来实现。以下是几种常见的方法: 使用动态组件 动态组件允许根据当前选中的Tab动态切换显示内容。定义一个组件…

vue.js实现轮播

vue.js实现轮播

Vue.js 实现轮播功能 使用第三方库(推荐) Vue.js 生态中有许多成熟的轮播组件库,例如 vue-awesome-swiper 或 swiper,它们功能丰富且易于集成。 安装 swip…

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现轮播图

js实现轮播图

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

js实现打印

js实现打印

使用window.print()方法实现打印 在JavaScript中,可以通过调用window.print()方法直接触发浏览器的打印功能。这会打开系统的打印对话框,用户可以选择打印机和设置打印选项…

js实现pdf在线预览

js实现pdf在线预览

使用PDF.js实现PDF在线预览 PDF.js是由Mozilla开发的一个开源JavaScript库,可以在网页中直接渲染PDF文件。以下是实现PDF在线预览的步骤: 引入PDF.js库 在H…