CSS+DIV+JS树形2层菜单,支持FF

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=gb2312">
<title>Div+CSS+JS树型菜单,可刷新</title>
<metaname="description"content="http://www.livepo.com">
<styletype="text/css">
<!--
*{margin:0;padding:0;border:0;}
body{font-family:arial,宋体,serif;font-size:12px;}
#nav{width:180px;line-height:24px;list-style-type:none;text-align:left;/*定义整个ul菜单的行高和背景色*/}
/*==================一级目录===================*/
#nava{width:160px;display:block;padding-left:20px;/*Width(一定要),否则下面的Li会变形*/}
#navli{background:#CCC;/*一级目录的背景色*/border-bottom:#FFF1pxsolid;/*下面的一条白边*/float:left;/*float:left,本不应该设置,但由于在Firefox不能正常显示继承Nav的width,限制宽度,li自动向下延伸*/}
#navlia:hover{background:#CC0000;/*一级目录onMouseOver显示的背景色*/}
#nava:link{color:#666;text-decoration:none;}
#nava:visited{color:#666;text-decoration:none;}
#nava:hover{color:#FFF;text-decoration:none;font-weight:bold;}
/*==================二级目录===================*/
#navliul{list-style:none;text-align:left;}
#navliulli{background:#EBEBEB;/*二级目录的背景色*/}
#navliula{padding-left:20px;width:160px;/*padding-left二级目录中文字向右移动,但Width必须重新设置=(总宽度-padding-left)*/}
/*下面是二级目录的链接样式*/
#navliula:link{color:#666;text-decoration:none;}
#navliula:visited{color:#666;text-decoration:none;}
#navliula:hover{color:#F3F3F3;text-decoration:none;font-weight:normal;background:#CC0000;/*二级onmouseover的字体颜色、背景色*/}
/*==============================*/
#navli:hoverul{left:auto;}
#navli.sfhoverul{left:auto;}
#content{clear:left;}
#navul.collapsed{display:none;}
#PARENT{width:300px;padding-left:20px;}
/*==================三级目录===================*/
#navliulliul{list-style:none;text-align:left;}
#navliulliulli{background:#EBEBEB;/*二级目录的背景色*/}
#navliulliullia{padding-left:20px;width:160px;/*padding-left二级目录中文字向右移动,但Width必须重新设置=(总宽度-padding-left)*/}
/*下面是二级目录的链接样式*/
#navliulliullia:link{color:#666;text-decoration:none;}
#navliulliullia:visited{color:#666;text-decoration:none;}
#navliulliullia:hover{color:#F3F3F3;text-decoration:none;font-weight:normal;background:#CC0000;/*二级onmouseover的字体颜色、背景色*/}
-->
</style>
</head>

<body>
<divid="PARENT">

<ulid="nav">

<li><ahref="#Menu=ChildMenu1"onclick="DoMenu('ChildMenu1')">1</a>
<ulid="ChildMenu1"class="collapsed">
<li><ahref="http://www.netany.net"target="_blank">11</a></li>
<li><ahref="http://www.netany.net"target="_blank">12</a></li>
<li><ahref="http://www.netany.net"target="_blank">13</a></li>
<li><ahref="http://www.netany.net"target="_blank">14</a></li>
</ul>
</li>

<li><ahref="#Menu=ChildMenu2"onclick="DoMenu('ChildMenu2')">2</a>
<ulid="ChildMenu2"class="collapsed">
<li><ahref="#">21</a></li>
<li><ahref="#">22</a></li>
<li><ahref="#">23</a></li>
<li><ahref="#">24</a></li>
<li><ahref="#">25</a></li>
<li><ahref="#">26</a></li>
<li><ahref="#">27</a></li>
<li><ahref="#">28</a></li>
</ul>
</li>

<li><ahref="#Menu=ChildMenu3"onclick="DoMenu('ChildMenu3')">3</a>
<ulid="ChildMenu3"class="collapsed">
<li><ahref="#">b1</a></li>
<li><ahref="#">b2</a></li>
<li><ahref="#">b3</a></li>
</ul>
</li>

<li><ahref="#Menu=ChildMenu4"onclick="DoMenu('ChildMenu4')">4</a>
<ulid="ChildMenu4"class="collapsed">
<li><ahref="#">c1</a></li>
<li><ahref="#">c2</a></li>
<li><ahref="#">c3</a></li>
</ul>
</li>

<li><ahref="#Menu=ChildMenu5"onclick="DoMenu('ChildMenu5')">5</a>
<ulid="ChildMenu5"class="collapsed">
<li><ahref="#">d1</a></li>
<li><ahref="#">d2</a></li>
<li><ahref="#">d3</a></li>
</ul>
</li>

<li><ahref="#Menu=ChildMenu6"onclick="DoMenu('ChildMenu6')">6</a>
<ulid="ChildMenu6"class="collapsed">
<li><ahref="#">e1</a></li>
<li><ahref="#">e2</a></li>
<li><ahref="#">e3</a></li>
</ul>
</li>

<li><ahref="#Menu=ChildMenu7"onclick="DoMenu('ChildMenu7')">7</a>
<ulid="ChildMenu7"class="collapsed">
<li><ahref="#">f1</a></li>
<li><ahref="#">f2</a></li>
<li><ahref="#">f3</a></li>
</ul>
</li>

<li><ahref="#Menu=ChildMenu8"onclick="DoMenu('ChildMenu8')">8</a>
<ulid="ChildMenu8"class="collapsed">
<li><ahref="#">f1</a></li>
<li><ahref="#">f2</a></li>
<li><ahref="#">f3</a></li>
</ul>
</li>

</ul>
</div>
</body>
</html>
<scripttype=text/javascript><!--
varLastLeftID="";

functionmenuFix(){
varobj=document.getElementById("nav").getElementsByTagName("li");

for(vari=0;i<obj.length;i++){
obj[i].onmouseover=function(){
this.className+=(this.className.length>0?"":"")+"sfhover";
}
obj[i].onMouseDown=function(){
this.className+=(this.className.length>0?"":"")+"sfhover";
}
obj[i].onMouseUp=function(){
this.className+=(this.className.length>0?"":"")+"sfhover";
}
obj[i].onmouseout=function(){
this.className=this.className.replace(newRegExp("(?|^)sfhover\\b"),"");
}
}
}

functionDoMenu(emid)
{
varobj=document.getElementById(emid);
obj.className=(obj.className.toLowerCase()=="expanded"?"collapsed":"expanded");
if((LastLeftID!="")&&(emid!=LastLeftID))//关闭上一个Menu
{
document.getElementById(LastLeftID).className="collapsed";
}
LastLeftID=emid;
}

functionGetMenuID()
{

varMenuID="";
var_paramStr=newString(window.location.href);

var_sharpPos=_paramStr.indexOf("#");

if(_sharpPos>=0&&_sharpPos<_paramStr.length-1)
{
_paramStr=_paramStr.substring(_sharpPos+1,_paramStr.length);
}
else
{
_paramStr="";
}

if(_paramStr.length>0)
{
var_paramArr=_paramStr.split("&");
if(_paramArr.length>0)
{
var_paramKeyVal=_paramArr[0].split("=");
if(_paramKeyVal.length>0)
{
MenuID=_paramKeyVal[1];
}
}
/*
if(_paramArr.length>0)
{
var_arr=newArray(_paramArr.length);
}

//取所有#后面的,菜单只需用到Menu
//for(vari=0;i<_paramArr.length;i++)
{
var_paramKeyVal=_paramArr[i].split('=');

if(_paramKeyVal.length>0)
{
_arr[_paramKeyVal[0]]=_paramKeyVal[1];
}
}
*/
}

if(MenuID!="")
{
DoMenu(MenuID)
}
}

GetMenuID();//*这两个function的顺序要注意一下,不然在Firefox里GetMenuID()不起效果
menuFix();
--></script>
<think>我们使用Ant Design Vue的Tree组件来实现四树形结构,并自定义节点样式。 根据引用[4],在Vue中,如果使用异步数据,需要注意在数据返回后再实例化Tree,并且当有expandedKeys时,defaultExpandAll将失效。 同时,引用[2]展示了如何自定义渲染节点(使用插槽或render函数)。 步骤: 1. 准备四树形结构数据(treeData),每通过children属性嵌套。 2. 使用a-tree组件,并传入treeData。 3. 自定义节点样式:通过插槽(scoped slot)自定义节点内容,或者使用treeNodeRender属性(在Vue3中,可以使用v-slot:title)。 4. 控制展开:可以使用defaultExpandAll(注意异步数据的问题)或者通过expandedKeys和defaultExpandedKeys控制。 注意:在Vue3中,我们可以使用v-if来确保数据加载完成后再渲染Tree(引用[4]提到)。 示例代码(使用Vue3 + Composition API):</think>### Ant Design Vue 实现四树形组件并自定义样式 在 Ant Design Vue 中实现四树形结构并自定义样式,主要通过以下步骤完成: #### 1. 准备树形结构数据 使用嵌套的 `children` 属性构建四结构: ```javascript const treeData = ref([ { title: '一级节点', key: '0-0', children: [ { title: '二级节点', key: '0-0-0', children: [ { title: '三级节点', key: '0-0-0-0', children: [ // 第四节点 { title: '四级节点-1', key: '0-0-0-0-0' }, { title: '四级节点-2', key: '0-0-0-0-1' } ] } ] } ] } ]); ``` #### 2. 基本树形组件实现 ```vue <template> <a-tree :tree-data="treeData" :defaultExpandAll="true" :show-line="true" /> </template> <script setup> import { ref } from 'vue'; // 树形数据(同上) const treeData = ref([...]); </script> ``` #### 3. 自定义节点样式(关键步骤) 使用 `scopedSlots` 自定义节点渲染: ```vue <template> <a-tree :tree-data="treeData" :defaultExpandAll="true" > <!-- 自定义节点内容 --> <template #title="{ key, title }"> <div :class="getNodeClass(key)"> {{ title }} </div> </template> </a-tree> </template> <script setup> // 根据级返回不同样式类 const getNodeClass = (key) => { const level = key.split('-').length - 1; return [ 'tree-node', `level-${level}`, // 按级添加类名 level === 4 ? 'leaf-node' : '' // 四级节点特殊样式 ]; }; </script> <style scoped> /* 基础节点样式 */ .tree-node { padding: 4px 8px; border-radius: 4px; } /* 按级设置不同样式 */ .level-1 { background-color: #f0f9ff; } .level-2 { background-color: #e6f7ff; } .level-3 { background-color: #d6e4ff; } .level-4 { background-color: #b7eb8f; font-weight: bold; } /* 四级节点特殊样式 */ .leaf-node { border-left: 3px solid #52c41a; } </style> ``` #### 4. 完整功能示例(含展开控制) ```vue <template> <div> <a-button @click="expandAll">全部展开</a-button> <a-button @click="collapseAll">全部折叠</a-button> <a-tree :tree-data="treeData" :expandedKeys="expandedKeys" @expand="handleExpand" > <template #title="{ key, title }"> <div :class="getNodeClass(key)"> <span v-if="key.split('-').length === 5"> <a-icon type="tag" /> </span> {{ title }} </div> </template> </a-tree> </div> </template> <script setup> import { ref } from 'vue'; const treeData = ref([...]); // 同上 const expandedKeys = ref(['0-0', '0-0-0', '0-0-0-0']); // 默认展开前三级 const handleExpand = (keys) => { expandedKeys.value = keys; }; const expandAll = () => { // 递归获取所有可展开节点的key const getAllKeys = (nodes) => { let keys = []; nodes.forEach(node => { keys.push(node.key); if (node.children) { keys = keys.concat(getAllKeys(node.children)); } }); return keys; }; expandedKeys.value = getAllKeys(treeData.value); }; const collapseAll = () => { expandedKeys.value = []; }; // 同上 const getNodeClass = (key) => { ... }; </script> ``` #### 5. 关键注意事项 1. **级判断**:通过 `key.split('-').length` 判断节点级 ```javascript const level = key.split('-').length - 1; // 0为根节点 ``` 2. **异步数据加载**(引用[4]): ```vue <a-tree v-if="treeData.length > 0" ... /> ``` 3. **样式穿透**:使用 `:deep()` 修改组件内置样式 ```css :deep(.ant-tree-node-content-wrapper) { padding: 2px 5px; } ``` 4. **图标自定义**: ```vue <template #icon="{ expanded }"> <a-icon :type="expanded ? 'folder-open' : 'folder'" /> </template> ``` 5. **性能优化**: ```vue <a-tree :virtual="true" :height="400" /> ``` #### 6. 自定义样式扩展方案 1. **按级设置不同图标**: ```vue <template #icon="{ data }"> <a-icon v-if="data.key.split('-').length === 2" type="database" /> <a-icon v-else-if="data.key.split('-').length === 5" type="file" /> <a-icon v-else type="folder" /> </template> ``` 2. **悬停效果**: ```css .tree-node:hover { background-color: #e6f7ff; transition: background-color 0.3s; } ``` 3. **响应式设计**: ```css @media (max-width: 768px) { .tree-node { padding: 2px 4px; font-size: 12px; } } ``` Ant Design Vue 的 Tree 组件通过灵活的插槽机制和样式覆盖能力,可以轻松实现多树形结构和深度自定义样式[^1][^4]。 --- ### 相关问题 1. 如何在 Ant Design Vue 树形组件中实现动态数据加载? 2. 树形组件如何实现节点拖拽排序功能? 3. 如何为不同级的节点设置不同的右键菜单? 4. 树形结构数据量过大时,有哪些虚拟滚动优化方案? 5. 如何实现树形组件的搜索过滤功能?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值