You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DevExtreme侧边导航TreeView项如何改为<a>标签支持新标签页打开

DevExtreme TreeView 菜单项实现右键「在新标签页打开」方案

不需要手动操作DOM修改渲染结果,直接使用组件官方提供的项自定义模板能力即可实现,稳定性远高于事后DOM操作,不会因为组件重渲染失效。

实现步骤

  • 第一步:确认菜单数据源字段
    你的菜单项配置已经有path字段作为唯一key和路由地址,直接复用该字段作为链接跳转地址即可,不需要额外新增字段。
  • 第二步:修正原有配置错误
    你当前代码里的expandedExpr="false"是错误配置,该属性的作用是指定数据项中控制节点展开状态的字段名,而非直接传入展开状态值,默认全折叠可以给每个菜单项加expanded: false字段,或者在onContentReady回调中调用TreeView实例的collapseAll()方法实现。
  • 第三步:通过itemTemplate自定义节点渲染结构
    给TreeView组件添加itemTemplate配置,区分父级菜单(带子菜单)和叶子节点:父级节点保留普通文本渲染避免展开/跳转冲突,叶子节点渲染为<a>标签(或React Router的Link组件,适配单页应用),保留原生链接的右键菜单能力。

完整代码示例

import { TreeView } from 'devextreme-react/tree-view';
import { Link } from 'react-router-dom'; // 单页应用引入路由链接组件,纯多页应用可直接用原生a标签
import { useRef } from 'react';

// 菜单项配置示例
const items = [
  {
    path: '/dashboard',
    text: '工作台',
    expanded: false, // 控制默认折叠状态
  },
  {
    path: '/system',
    text: '系统管理',
    expanded: false,
    items: [ // 存在items字段即为父级菜单
      {
        path: '/system/user',
        text: '用户管理'
      },
      {
        path: '/system/role',
        text: '角色管理'
      }
    ]
  }
];

export default function SideMenu() {
  const treeViewRef = useRef(null);

  const selectedItemChanged = (e) => {
    // 保留你原有的菜单点击逻辑
  };

  const onMenuReady = (e) => {
    // 保留你原有的菜单加载完成逻辑,如果需要默认全折叠可以放开下面这行
    // e.component.collapseAll();
  };

  return (
    <TreeView
      ref={treeViewRef}
      items={items}
      keyExpr={'path'}
      selectionMode={'single'}
      focusStateEnabled={false}
      expandEvent={'click'}
      onItemClick={selectedItemChanged}
      onContentReady={onMenuReady}
      width={'100%'}
      expandedExpr="expanded"
      itemTemplate={(itemData) => {
        // 带子菜单的父节点渲染为普通文本,避免和展开操作冲突
        if (Array.isArray(itemData.items) && itemData.items.length > 0) {
          return <span className="dx-treeview-item-text">{itemData.text}</span>
        }
        // 叶子节点渲染为链接,支持原生右键菜单
        return (
          <Link
            to={itemData.path}
            className="dx-treeview-item-text"
            onClick={(e) => {
              // 阻止链接默认跳转,左键点击完全复用原有TreeView的选中、跳转逻辑
              e.preventDefault();
            }}
          >
            {itemData.text}
          </Link>
        )
      }}
    />
  )
}

注意事项

  • 自定义链接添加dx-treeview-item-text类名即可自动继承DevExtreme默认的菜单样式,无需额外写CSS对齐外观
  • 阻止左键点击的默认跳转行为不会影响右键「在新标签页打开」的原生能力,新标签页打开时会直接访问对应路由地址,符合用户操作预期
  • 不推荐在onContentReady里手动操作DOM包裹a标签,TreeView展开折叠、动态更新菜单时会重新渲染DOM,手动修改的结构会被覆盖丢失。

内容的提问来源于stack exchange,提问作者khajehmiri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:39:03