element UI el-tree 自定义 (改变字体颜色)

本文详细介绍如何在Element UI框架中使用树形组件,并通过自定义渲染函数实现不同类型的节点样式,包括销售类别、秒杀类别和普通类别,同时提供CSS样式代码用于颜色区分。

1.

<el-tree
  :data="data"
  :props="defaultProps"
  node-key="id"
  :default-expanded-keys="defaultExpanded"
  :render-content="renderContent"        ///////////注意这里
  @node-click="handleNodeClick"/>

 

 

2.

data:

defaultProps: {
  children: 'children',
  label: 'name'
},

methods:

//   判断 type     选择自己想要的样式   

renderContent(h, { node, data, store }) {
  return(<span class={data.type == 1?'selling-category':(data.type == 2?'seckill-category':'common-category')} style="font-size:14px;cursor:pointer">{node.label}</span>)
},

注意:renderContent中需要使用 jsx 语法

https://blog.youkuaiyun.com/weixin_33911824/article/details/93575421

3.

css:

.selling-category{
  color:#7195FA;
}
.seckill-category{
  color:#D874FA;
}
.common-category{
  color:#FC5D5D
}
<think> 我们参考用户提供的引用内容,总结出在Element UIel-tree组件中自定义图标为加号和减号的方法主要涉及两个方面: 1. 使用插槽(slot)自定义图标内容,根据节点状态(是否展开、是否有子节点)动态切换图标。 2. 隐藏组件自带的展开箭头(通常通过CSS设置隐藏)。 具体步骤: 步骤1:在el-tree组件中使用名为“default”的插槽(在Vue中通常使用作用域插槽)自定义图标。 步骤2:在插槽中,通过判断节点的属性(如expanded和是否有子节点)来决定显示加号还是减号图标。 步骤3:通过CSS隐藏组件自带的展开箭头(避免出现两个图标)。 以下是具体实现: 1. 模板部分(使用作用域插槽): ```vue <el-tree :data="data" :props="defaultProps" :expand-on-click-node="false"> <!-- 使用作用域插槽自定义节点内容 --> <span slot-scope="{ node, data }" class="custom-tree-node"> <!-- 自定义图标:根据节点状态显示加号或减号 --> <!-- 注意:如果节点没有子节点,则不需要显示加减号(或者显示为其他图标,如圆圈) --> <i v-if="node.childNodes.length === 0" class="el-icon-circle-close"></i> <i v-else :class="node.expanded ? 'el-icon-remove-outline' : 'el-icon-circle-plus-outline'"></i> <span>{{ node.label }}</span> </span> </el-tree> ``` 2. 样式部分(隐藏自带的展开箭头): 在引用[2]和[3]中提到了隐藏自带箭头的方法,这里我们采用设置透明度为0的方法(同时保留其占位,避免影响布局): ```css /* 隐藏自带的展开箭头 */ .el-tree-node__content > .el-tree-node__expand-icon { opacity: 0; position: absolute; /* 绝对定位,使其脱离文档流,避免占用空间 */ } .el-tree-node__content { position: relative; /* 为绝对定位的子元素提供相对定位 */ } ``` 3. 注意:由于我们隐藏了自带的展开箭头,但是自定义图标并没有点击展开/折叠的功能,所以需要将点击事件绑定到自定义图标上?实际上,el-tree的节点点击区域是整个节点(包括图标和文字)。但是,我们自定义的图标并没有触发展开/折叠,因为隐藏的原生箭头仍然在节点内容区域内(虽然透明,但占据位置),所以点击原来的位置仍然有效。 但是,如果我们希望点击自定义图标也能触发展开/折叠,我们可以给自定义图标添加点击事件,并调用node的展开折叠方法。例如: ```vue <i v-else :class="node.expanded ? 'el-icon-remove-outline' : 'el-icon-circle-plus-outline'" @click="toggleExpand(node)"> </i> ``` 在方法中: ```javascript methods: { toggleExpand(node) { node.expanded = !node.expanded; } } ``` 然而,需要注意的是,el-tree的节点展开状态是由节点自身的expanded属性控制的,并且tree组件内部会监听这个属性。但是,直接修改可能不会触发视图更新,所以更推荐使用tree组件的setExpanded方法(需要获取tree实例)或者通过触发节点点击事件。 但是,考虑到el-tree本身的设计,点击整个节点(包括图标和文字)都会触发切换,所以如果我们只是自定义图标样式,隐藏了自带箭头,那么点击位置实际上还是覆盖在自定义图标上(因为原箭头是绝对定位覆盖在自定义图标的位置上)。因此,我们可以通过调整CSS,让原箭头的区域覆盖整个节点内容区域,或者将原箭头的点击区域扩大到整个节点(实际上默认就是整个节点触发)。所以,如果我们只是隐藏了箭头,但保留了它的位置(通过绝对定位覆盖在自定义图标上),那么点击自定义图标的位置实际上会触发原箭头的点击事件(因为它在上面)。这样,我们就不需要额外绑定事件。 但是,如果隐藏箭头后,点击自定义图标的位置没有触发展开折叠,可能是因为原箭头虽然透明,但被自定义图标遮挡了(因为绝对定位的层级关系)。所以,我们需要确保原箭头的层级在自定义图标之下(或者不遮挡),但我们隐藏了它,所以点击事件应该由节点内容捕获。 实际上,更简单的方法是不使用绝对定位隐藏原箭头,而是直接通过设置`display: none`,但这样会失去占位,所以我们可以设置原箭头宽度为0,然后通过调整自定义图标的样式来占据原来箭头的位置。 引用[3]提供了一种方法:通过设置原箭头的宽度为0,然后自定义图标使用背景图片,并且通过伪元素来设置。但这里我们使用字体图标,所以可以调整原箭头的宽度为0,然后自定义图标设置margin-left调整位置。 因此,另一种隐藏原箭头的方法(不占用空间): ```css .el-tree-node__content > .el-tree-node__expand-icon { display: none; } ``` 然后,在自定义图标的元素上,我们需要手动添加左边距来模拟原箭头的缩进(因为原箭头隐藏后,自定义图标需要占据原位置): ```vue <i v-if="node.childNodes.length === 0" class="el-icon-circle-close" style="margin-left: 16px;"></i> <i v-else :class="node.expanded ? 'el-icon-remove-outline' : 'el-icon-circle-plus-outline'" style="margin-left: 16px;"></i> ``` 但是,这样就需要为不同层级的节点设置不同的缩进(因为树形结构有层级缩进)。实际上,el-tree的层级缩进是由`el-tree-node__content`的padding-left实现的,而原箭头是放在这个padding-left区域内的。所以隐藏原箭头后,我们自定义的图标需要放在原箭头的位置(即padding-left区域内)。因此,我们可以将自定义图标设置为绝对定位,并调整位置到最左边。 综合以上,我们采用以下方案: 1. 隐藏原箭头(使用`display:none`) 2. 在自定义节点内容时,将自定义图标绝对定位到原箭头的位置(通过调整left值)。 调整CSS: ```css .custom-tree-node { position: relative; padding-left: 16px; /* 留出原箭头的位置 */ } .custom-tree-node > i:first-child { position: absolute; left: -16px; /* 将图标移动到原箭头的位置 */ } ``` 这样,自定义图标就会显示在原箭头的位置,并且点击节点任何地方(包括自定义图标)都会触发展开/折叠,因为节点点击事件绑定在整个`.el-tree-node__content`上。 但是,我们需要注意,如果节点有嵌套层级,每一层都会有一个原箭头,每个原箭头的位置都是通过`padding-left`逐级增加的。所以我们不能简单地将自定义图标固定向左移动16px,而应该根据节点的层级动态调整?实际上,el-tree已经通过`padding-left`实现了层级缩进,我们只需要在原箭头的位置(即每一层级的最开始16px区域内)放置我们的自定义图标。所以,我们只需要将自定义图标绝对定位到该节点的`.el-tree-node__content`的最左侧(即当前层级缩进区域的开始位置)。 因此,修改后的CSS: ```css /* 隐藏原箭头 */ .el-tree-node__expand-icon { display: none; } /* 自定义节点内容容器,需要相对定位以便于绝对定位图标 */ .custom-tree-node { position: relative; flex: 1; /* 确保宽度填满 */ } /* 自定义图标:绝对定位到左侧,距离左侧0,但原箭头的位置是在每个节点的内容区域的左侧,而节点内容区域已经通过padding-left缩进 */ /* 因此,我们的图标需要放在该节点内容区域的padding-left区域内 */ .custom-tree-node > i:first-child { position: absolute; left: -16px; /* 因为原箭头宽度一般是16px,所以向左移动16px,这样图标就会出现在原箭头的位置 */ } ``` 但是,这样设置后,第一层节点的自定义图标会向左超出16px,而第二层节点因为缩进了16px(假设每层缩进16px),所以图标的位置在第二层节点的左侧16px处,实际上是在第一层节点的内容区域内。所以我们需要根据层级动态调整?实际上,不需要,因为每一层节点的内容区域(.el-tree-node__content)的padding-left都是相对于父节点增加的,而我们的自定义图标是相对于当前节点内容区域的左侧绝对定位的(即相对于当前节点的padding-left的起始位置)。所以,我们只需要将图标向左移动16px,就可以覆盖在该节点原箭头的位置(原箭头也是在该节点的padding-left区域内显示的)。 注意:每一层节点的缩进是由`.el-tree-node`的`padding-left`实现的,而我们自定义的图标放在`.custom-tree-node`内,它本身在`.el-tree-node__content`内(这个元素没有缩进,缩进是在其父元素上设置的)。所以,我们只需要向左移动16px,就能够覆盖在当前节点原箭头的位置(因为原箭头也是相对于当前节点内容区域定位的)。 但是,这种方法需要确保每一层的缩进都是16px(Element UI默认是16px)。如果缩进值改变,需要相应调整。 综上所述,我们给出完整的代码示例: 模板部分: ```vue <template> <el-tree :data="data" :props="defaultProps" :expand-on-click-node="false" node-key="id" > <!-- 使用作用域插槽 --> <span slot-scope="{ node, data }" class="custom-tree-node"> <!-- 自定义图标:根据节点状态显示加号或减号 --> <!-- 注意:我们使用node.childNodes.length判断是否有子节点(或者使用node.data.children,根据数据结构) --> <!-- 这里假设数据结构中,叶子节点没有children属性或children为空数组 --> <i v-if="!node.childNodes || node.childNodes.length === 0" class="el-icon-circle-close"></i> <i v-else :class="node.expanded ? 'el-icon-remove-outline' : 'el-icon-circle-plus-outline'"></i> <span>{{ node.label }}</span> </span> </el-tree> </template> ``` 样式部分(在style标签内,注意使用scoped或全局): ```css /* 隐藏原箭头 */ .el-tree-node__expand-icon { display: none; } /* 自定义节点样式 */ .custom-tree-node { position: relative; /* 留出原箭头的位置,因为隐藏了原箭头,所以这里不需要额外留空间,但原箭头位置在padding-left区域内,我们通过绝对定位把图标放过去 */ /* 不需要设置padding-left,因为el-tree-node__content已经有padding-left了 */ } .custom-tree-node > i:first-child { position: absolute; left: -16px; /* 向左移动到原箭头的位置 */ top: 50%; transform: translateY(-50%); /* 垂直居中 */ } ``` 这样,就实现了将图标自定义为加号和减号,并且隐藏了原箭头,同时保证了点击节点(包括图标区域)能够展开/折叠。 注意:如果树形结构的数据中,非叶子节点即使没有子节点(比如动态加载的情况下,初始时children为空),那么可能无法显示加减号。因此,可能需要根据实际情况调整判断条件。例如,如果某个节点是叶子节点(isLeaf属性),则显示无加减号(或另一种图标),否则根据展开状态显示加减号。 另外,关于引用[4]中提到的展开/折叠全部节点的方法,用户也可以参考,但此处主要需求是自定义图标,故不展开。 最后,生成相关问题: </think> 在 Element UIel-tree 组件中,将节点图标自定义为加号(展开前)和减号(展开后)的实现方法如下,综合参考了站内多个解决方案: ### 完整实现步骤 1. **使用作用域插槽自定义图标** ```vue <el-tree :data="data"> <template #default="{ node, data }"> <!-- 判断节点类型 --> <i v-if="node.isLeaf" class="el-icon-circle-close" /> <!--子节点图标 --> <i v-else :class="node.expanded ? 'el-icon-remove' : 'el-icon-circle-plus'" /> <!-- 非叶子节点动态图标 --> <span>{{ node.label }}</span> </template> </el-tree> ``` - `node.expanded` 属性控制展开状态(true=展开,false=折叠)[^1] -子节点使用固定图标(如 `el-icon-circle-close`) - 非叶子节点根据状态切换 `el-icon-circle-plus`(加号)和 `el-icon-remove`(减号) 2. **隐藏组件自带箭头 (关键步骤)** ```css /* 隐藏原生箭头 */ .el-tree-node__content > .el-tree-node__expand-icon { display: none; /* 或 opacity:0 保留占位 */ } ``` 使用 `opacity:0` 可保留点击区域,使用 `display:none` 则完全移除[^2] 3. **添加展开/折叠动画 (可选)** ```css .el-tree-node__expand-icon { transition: transform 0.3s; /* 旋转动画 */ } .el-tree-node__expand-icon.expanded { transform: rotate(0deg); /* 禁用旋转效果 */ } ``` ### 完整代码示例 ```vue <template> <el-tree :data="treeData" node-key="id"> <template #default="{ node, data }"> <!-- 动态切换加减号 --> <i v-if="node.childNodes.length > 0" :class="node.expanded ? 'el-icon-remove' : 'el-icon-circle-plus'" style="margin-right:5px" /> <span>{{ node.label }}</span> </template> </el-tree> </template> <style scoped> /* 隐藏原生箭头 */ :deep(.el-tree-node__content > .el-tree-node__expand-icon) { opacity: 0; width: 0; } </style> ``` ### 注意事项 1. **图标选择建议**: - 加号图标:`el-icon-circle-plus` / `el-icon-plus` - 减号图标:`el-icon-remove` / `el-icon-minus` - 可在 [Element UI 图标库](https://element.eleme.cn/#/zh-CN/component/icon) 选择合适图标 2. **动态加载的特殊处理**: ```vue <i v-if="data.children && data.children.length > 0" ... /> ``` 未加载子节点时需判断 `hasChildren` 属性 3. **点击事件穿透**: 隐藏原生箭头时需确保自定义图标能触发 `expand-change` 事件,可添加: ```css .el-tree-node__content { position: relative /* 保证点击区域正确 */ [^2] } ``` ### 扩展功能 实现全局展开/折叠控制按钮: ```vue <el-button @click="toggleExpandAll">展开/收起</el-button> <script> export default { methods: { toggleExpandAll() { const nodes = this.$refs.tree.store._getAllNodes(); nodes.forEach(node => node.expanded = !this.isExpandAll); this.isExpandAll = !this.isExpandAll; } }, data() { return { isExpandAll: false } } } </script> ``` **注意**:需在 `<el-tree>` 设置 `node-key` 属性[^4]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值