自定义《element-UI》el-tree 的样式 、亲测管用

这篇博客介绍了如何使用Vue.js结合Element UI库,通过修改箭头图标、添加动画、自定义不同层级图标、添加复选框以及封装Vue3+TS组件,实现树形组件的五种不同定制方法。详细展示了模板、脚本和样式的代码实现,包括切换箭头、添加动画效果、自定义一二级图标以及在节点前添加复选框的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 第一种 切换箭头打开和折叠 :

 第二种 修改箭头打开和折叠 + 动画:

 第三种 修改箭头打开和折叠 + 一二级自定义图标:

 第四种在el-tree前加复选框和图标

 第五种 Vue3 + ts 封装


ab2e230e8501412b9b9e7bedd2d0dc69.gif

第一种 切换箭头打开和折叠 :

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAMC7mtLvlnKjpo47mtarph4w=,size_20,color_FFFFFF,t_70,g_se,x_16

<template>
  <div class="tree">
    <el-tree
      :data="data5"
      :props="props"
      show-checkbox
      node-key="id"
      default-expand-all
    >
    </el-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      props: {
        label: "label",
        children: "children",
      },
      data5: [
        {
          id: 1,
          label: "一级 1",
          icon: "el-icon-success",
          children: [
            {
              id: 4,
              label: "二级 1-1",
              children: [
                {
                  id: 9,
                  label: "三级 1-1-1",
                  icon: "el-icon-info",
                },
                {
                  id: 10,
                  label: "三级 1-1-2",
                },
              ],
            },
          ],
        },
        {
          id: 2,
          label: "一级 2",
          children: [
            {
              id: 5,
              label: "二级 2-1",
            },
            {
              id: 6,
              label: "二级 2-2",
            },
          ],
        },
        {
          id: 3,
          label: "一级 3",
          children: [
            {
              id: 7,
              label: "二级 3-1",
            },
            {
              id: 8,
              label: "二级 3-2",
            },
          ],
        },
      ],
    };
  },
};
</script>
<style lang="scss" scoped>


::v-deep .el-icon-caret-right:before {
  content: "y";
  font-size: 16px;
}

::v-deep .expanded:before {
  content: "x";
  font-size: 16px;
}
</style>

 第二种 修改箭头打开和折叠 + 动画:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAMC7mtLvlnKjpo47mtarph4w=,size_20,color_FFFFFF,t_70,g_se,x_16

<template>
  <div class="tree">
    <el-tree
      icon-class="user"
      :data="data5"
      :props="props"
      show-checkbox
      node-key="id"
      default-expand-all
    >
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span> <i :class="node.icon"></i>{{ node.label }} </span>
      </span>
    </el-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      props: {
        label: "label",
        children: "children",
      },
      data5: [
        {
          id: 1,
          label: "一级 1",
          icon: "el-icon-success",
          children: [
            {
              id: 4,
              label: "二级 1-1",
              children: [
                {
                  id: 9,
                  label: "三级 1-1-1",
                  icon: "el-icon-info",
                },
                {
                  id: 10,
                  label: "三级 1-1-2",
                },
              ],
            },
          ],
        },
        {
          id: 2,
          label: "一级 2",
          children: [
            {
              id: 5,
              label: "二级 2-1",
            },
            {
              id: 6,
              label: "二级 2-2",
            },
          ],
        },
        {
          id: 3,
          label: "一级 3",
          children: [
            {
              id: 7,
              label: "二级 3-1",
            },
            {
              id: 8,
              label: "二级 3-2",
            },
          ],
        },
      ],
    };
  },
};
</script>
<style lang="scss" scoped>
/deep/.user {
  //   background: url("../../assets/logo.png");
  background: url("../../assets/logo.png");
  
  box-sizing: border-box;
  background-size: 100%;
  background-repeat: no-repeat;
}
/deep/.el-tree-node__expand-icon {
  transform: rotate(-90deg);
}
/deep/.el-tree-node__expand-icon.expanded {
  transform: rotate(0deg);
}
</style>

 第三种 修改箭头打开和折叠 + 一二级自定义图标:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAMC7mtLvlnKjpo47mtarph4w=,size_20,color_FFFFFF,t_70,g_se,x_16

<template>
  <div class="ov-container">
    <el-tree :data="data" :props="defaultProps">
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <i v-if="node.level == 1" class="province" />
        <i v-else-if="node.level == 2" class="city" />
        <i v-else-if="node.level == 3" />
        {{ data.label }}
      </span>
    </el-tree>
  </div>
</template>

<script>
export default {
  name: "index",
  data() {
    return {
      data: [
        {
          label: "一级 1",
          children: [
            {
              label: "二级 1-1",
              children: [
                {
                  label: "三级 1-1-1",
                },
              ],
            },
          ],
        },
        {
          label: "一级 2",
          children: [
            {
              label: "二级 2-1",
              children: [
                {
                  label: "三级 2-1-1",
                },
              ],
            },
            {
              label: "二级 2-2",
              children: [
                {
                  label: "三级 2-2-1",
                },
              ],
            },
          ],
        },
        {
          label: "一级 3",
          children: [
            {
              label: "二级 3-1",
              children: [
                {
                  label: "三级 3-1-1",
                },
              ],
            },
            {
              label: "二级 3-2",
              children: [
                {
                  label: "三级 3-2-1",
                },
              ],
            },
          ],
        },
        {
          label: "一级 4",
          children: [
            {
              label: "三级 3-2-1",
            },
          ],
        },
        {
          label: "一级 4",
        },
      ],
    };
  },
};
</script>

<style scoped lang="scss">
.ov-container {
  height: calc(100vh - 80px);
  background: #ffffff;
  border-radius: 5px;
  margin: 10px;
}

.province {
  background: url("../../assets/logo.png");
  width: 17px;
  height: 14px;
  display: inline-block;
   background-size: 100% 100%;

}

.city {
  background: url("../../assets/图片2.png") no-repeat;
  width: 17px;
  height: 14px;
  display: inline-block;
  background-size: 100% 100%;

}

.line {
  background: url("../../assets/百花.png") no-repeat;
  background-size: 100%;

  width: 17px;
  height: 14px;
  display: inline-block;
}

.data {
  background: url("../../assets/花朵.png") no-repeat;
  background-size: 100%;

  width: 17px;
  height: 14px;
  display: inline-block;
}

.el-tree /deep/ .el-tree-node__expand-icon.expanded {
  -webkit-transform: rotate(0deg);
  transform: rotate(0deg);
}
//有子节点 且未展开
.el-tree /deep/ .el-icon-caret-right:before {
//   background: url("../../assets/logo.png") no-repeat 0 0;
  content: "√";
  display: block;
  width: 12px;
  height: 12px;
  font-size: 16px;
  background-size: 100% 100%;
}
//有子节点 且已展开
.el-tree /deep/ .el-tree-node__expand-icon.expanded.el-icon-caret-right:before {
//   background: url("../../assets/logo.png") no-repeat 0 0;
  content: "x";
  display: block;
  width: 12px;
  height: 12px;
  font-size: 12px;
  background-size: 100% 100%;
}
//没有子节点
.el-tree /deep/.el-tree-node__expand-icon.is-leaf::before {
//    background: url("../../assets/logo.png") no-repeat 0 0;
  content: "";
  display: block;
  width: 12px;
  height: 12px;
  font-size: 16px;
  background-size: 100% 100%;
}
</style>

 第四种在el-tree前加复选框和图标

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAMC7mtLvlnKjpo47mtarph4w=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAMC7mtLvlnKjpo47mtarph4w=,size_20,color_FFFFFF,t_70,g_se,x_16

第五种 Vue3 + ts 封装

<template>
	<!-- 
	ref="treeRef" 用于获取树型组件的实例
	:check-strictly="checkStrictly" 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法
	:indent="0" 树节点的缩进距离,设为0即取消缩进。
	:show-checkbox="props.isShowCheckbox" 是否显示复选框,通过 props.isShowCheckbox 来控制。
	:default-expand-all="props.expandAll" 是否默认展开所有节点,通过 props.expandAll 来控制
	:default-checked-keys="props.checkedKeys" 默认选中的节点的 key 的数组
	:data="props.treeData" 展示数据 树的数据源,通过 props.treeData 来控制
	:props="defaultProps" 配置选项,设置树节点的属性,通过 defaultProps 来控制。
	:accordion="props.accordion" 是否每次只展开一个子树节点(手风琴),通过 props.accordion 来控制。
	node-key="id" 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
	@node-click="onCurAllNodes" 点击树节点触发的事件 onCurAllNodes 是该函数的名称。
	@node-expand="onHandleExpand" 节点被展开的事件 onHandleExpand 是该函数的名称。
	@check-change="getCheckedAllNodes" 勾选状态发生变化时的事件回调函数,getCheckedNodes 是该函数的名称。
	check-on-click-node 点击节点时选中节点,默认值为 false。

	<i :class="checkIconByNodeLevel(node)" />:根据节点的层级来动态设置节点前面的图标样式。
	{{ node.label }}:显示节点的标签文本。需要根据实际的数据结构来获取。props="defaultProps" 、数据源、node.label 三者需要保持一致。
	示例:
			<template>
				<zw-tree
					:treeData="treeData"
					@onCurAllNodes="onCurAllNodes"
					@getCheckedAllNodes="getCheckedAllNodes"
					@onHandleExpand="onHandleExpand"
				/>
			</template>

		<script setup lang="ts" name="Tree">
		import { ref } from 'vue';
		const treeData = ref([{}]);

		const onCurAllNodes = (data: object) => {
			console.log('当前节点下所有节点:', data);
		};

		const onHandleExpand = (data: object) => {
			console.log('展开节点时触发:', data);
		};
		const getCheckedAllNodes = (data: object) => {
			console.log('复选框改变:', data);
		};
		</script>

 -->
	<el-tree
		ref="treeRef"
		class="tree-line"
		:check-strictly="checkStrictly"
		:indent="0"
		:show-checkbox="props.isShowCheckbox"
		:default-expand-all="props.expandAll"
		:default-checked-keys="props.checkedKeys"
		:data="props.treeData"
		:props="defaultProps"
		:accordion="props.accordion"
		node-key="id"
		@node-click="onCurAllNodes"
		@node-expand="onHandleExpand"
		@check-change="getCheckedAllNodes"
		check-on-click-node
	>
		<template #default="{ node }">
			<i :class="checkIconByNodeLevel(node)" /> {{ node.label }}
		</template>
	</el-tree>
</template>

<script lang="ts" setup>
import { defineExpose, ref } from 'vue';
// 默认配置
const defaultProps = {
	children: 'children',
	label: 'label',
};

interface Tree {
	label: string;
	children?: Tree[];
}

const treeRef = ref();

const props = defineProps({
	// 树型数据
	treeData: {
		type: Array,
		default: () => {
			return [];
		},
	},
	// 是否全部展开
	expandAll: {
		type: Boolean,
		default: () => {
			return true;
		},
	},
	// 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法
	checkStrictly: {
		type: Boolean,
		default: () => {
			return false;
		},
	},
	checkedKeys: {
		type: Array,
		default: () => {
			return [];
		},
	},
	isShowCheckbox: {
		type: Boolean,
		default: () => {
			return true;
		},
	},
	accordion: {
		type: Boolean,
		default: () => {
			false;
		},
	},
});

// 根据节点层级显示不同的图标
const checkIconByNodeLevel = (node: {
	childNodes: [];
	expanded: boolean;
	data: { id: number };
}) => {
	if (node.childNodes.length == 0) {
		return 'iconfont icon-24gl-fileEmpty';
	} else {
		if (node.expanded) {
			return 'iconfont icon-wenjianzhankai';
		}
		return 'iconfont icon-jian';
	}
};

// 定义事件
const emits = defineEmits([
	'onCurAllNodes',
	'getCheckedAllNodes',
	'onHandleExpand',
]);

// 点击事件
const onCurAllNodes = (data: Tree) => {
	emits('onCurAllNodes', data);
};
// 复选框改变事件
const getCheckedAllNodes = (data: Tree) => {
	emits('getCheckedAllNodes', data);
};
// 展开事件
const onHandleExpand = (data: Tree) => {
	emits('onHandleExpand', data);
};

defineExpose({
	treeRef,
});
</script>

<style lang="scss" scoped>
@import url('/@/myIcon/iconfont.css');
</style>

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙雨溪 彩色之外

你的打赏是我创作的氮气加速动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值