效果图(在vue2项目开发中,实现了树形列表查看及筛选等交互,用清晰的层级结构展示信息)
开发步骤及代码,来喽!!无脑copy
1、组件基本框架
DeviceTree
是基于 Vue.js
和 Element UI
构建的树形组件。通过 el-tree
组件显示树状结构。组件的外部可通过传递 props
来控制是否显示复选框、设备过滤等特性。
核心字段和方法:
treeData
: 保存树的节点数据。currentKey
: 记录当前点击的节点。defaultProps
: 定义树节点的子元素 (children
),用于指定树的层次结构。handleNodeClick
: 响应节点点击事件,将点击的节点信息传递给父组件。handleNodeExpand
: 处理节点展开事件,防止同级节点全部展开,优化用户体验。
2、树形列表数据获取
组件在 created
钩子中调用 getTreeData
方法,从服务器获取树形结构数据,并将其格式化为适合 el-tree
的数据格式。(可以使用axios、ajaxs,我使用的是$http.post)
const res = this.$http.post("/后端接口", {userID: userid},{headers:headers});
res.then((ret) => {
var data = ret.data.data;
this.treeData = data.map(line => {
return {
NodeName: line.lineName,
id: line.lineID,
type: line.type,
icon: 'el-icon-location',
Children: line.areaList.map(area => ({
NodeName: area.areaName,
id: area.areaID,
type: area.type,
icon: 'el-icon-location-outline'
}))
};
});
});
3、组件交互功能
3.1过滤功能
- 使用
el-tree
组件的filter-node-method
实现对树节点的过滤。filterText
绑定到输入框的内容,当输入内容发生变化时,会触发树节点的过滤。
3.2 节点选择
getCheckedNodes
: 获取用户选择的复选框节点,用于在用户勾选复选框后,获取所选中的节点信息。clearChecked
: 清空所有勾选的节点。
3.3树节点的渲染
通过 eventRender
自定义树节点的渲染内容,显示节点的图标和名称,并根据需要是否显示复选框。
4、外部接口用于供父组件调用或监听
selectEquipTree
: 当用户点击某个节点时,触发该事件,向父组件传递所选节点的信息。updateData
: 更新树的数据,供外部组件调用,重新渲染树结构。
5、代码来喽
<template>
<div id="device-tree">
<div class="title">线路列表<span ref="spanRef"></span></div>
<el-input placeholder="输入关键字进行过滤" v-model="filterText" size="small">
</el-input>
<div class="tree-box">
<el-tree
:data="treeData"
:props="defaultProps"
ref="deviceTree"
node-key="id"
:default-expanded-keys="[currentKey]"
:current-node-key="currentKey"
:filter-node-method="filterNode"
:render-content="eventRender"
@node-click="handleNodeClick"
@node-expand="handleNodeExpand">
<span class="span-ellipsis" slot-scope="{ data }">
<i :class="data.icon" style="color: darkseagreen"></i>
<span class="span-tip" :title="data.linename">
{{ data.linename }}
</span>
</span>
<span class="span-ellipsis" slot-scope="{ data }">
<i :class="data.icon" style="color: darkseagreen"></i>
<span class="span-tip" :title="data.AreaName">
{{ data.AreaName }}
</span>
</span>
</el-tree>
</div>
</div>
</template>
<script>
export default {
name: "DeviceTree",
data() {
return {
filterText: "",
treeData: [],
currentKey: 1,
type: '',
defaultProps: {
children: "Children",
label: "NodeName",
isLeaf: "leaf",
},
};
},
props: {
parentNoclick: {
default: true,
type: Boolean,
},
isShowEquip: {
default: true,
type: Boolean,
},
equipFilter: {
default: "All",
type: String,
},
isShowCheck: {
default: false,
type: Boolean,
},
isShowRedCamera: {
default: false,
type: Boolean,
},
isShowTempreature: {
default: false,
type: Boolean,
},
props: {
equipData: {
type: Array,
default: () => [],
},
},
},
watch: {
filterText: function (val) {
this.$refs.tree.filter(val);
},
},
created() {
this.getTreeData();
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.NodeName.indexOf(value) !== -1;
},
handleNodeClick(data, node) {
this.currentKey = data.id;
this.type = data.type;
this.$emit("selectEquipTree", data);
},
handleNodeExpand(data, node) {
if (node.parent.data.NodeType == 1) {
var nodes = node.parent.childNodes;
nodes.forEach((n) => {
if (n.id != node.id) n.expanded = false;
});
this.$refs.tree.setCheckedKeys([], true);
}
},
updateData(newData) {
this.equipData = newData; // 更新树形组件的数据
this.refreshTree(); // 假设有一个方法用于刷新树
},
refreshTree() {
this.getTreeData();
},
// 获取树形结构
getTreeData() {
const token = localStorage.getItem('token')
const userid = localStorage.getItem('userid');
const headers = {
'Authorization': `Bearer ${token}`
};
const res = this.$http.post("/api/Area/GetAreaTreeList", {userID: userid},{headers:headers});
res.then((ret) => {
var data = ret.data.data;
this.treeData = data.map(line => {
return {
NodeName: line.lineName,
id: line.lineID,
type: line.type,
icon: 'el-icon-location',
Children: line.areaList.map(area => ({
NodeName: area.areaName,
id: area.areaID,
type: area.type,
icon: 'el-icon-location-outline'
}))
};
});
});
},
eventRender(h, { node, data, store }) {
if (this.isShowCheck) {
node.isLeaf = false;
if (data.NodeType == 1) {
node.isLeaf = true;
}
}
return (
<span class="span-ellipsis">
<i class={data.icon} style="color: darkseagreen"></i>
<span class="span-tip" title={data.NodeName}>
{data.NodeName}
</span>
</span>
// {}
);
},
getCheckedNodes() {
var keys = this.$refs.tree.getCheckedKeys(true);
let checkedNodes = [];
keys.forEach((key) => {
var node = this.$refs.tree.getNode(key);
checkedNodes.push(node);
});
return checkedNodes;
},
clearChecked() {
this.$refs.tree.setCheckedKeys([], true);
},
},
};
</script>
<style lang="less">
#device-tree {
width: 260px;
padding-left: 10px;
height: 100%;
.title {
color: #1bc3de;
font-size: 18px;
border-left: 3px solid #489fff;
margin-bottom: 10px;
padding-left: 10px;
text-align: left;
span {
color: #fff;
}
}
.el-input {
margin-bottom: 10px;
input {
width: 240px !important;
}
}
.tree-box {
height: calc(100% - 34px - 42px);
overflow: hidden;
overflow-y: visible;
.el-input {
margin-bottom: 10px;
input {
width: 240px !important;
}
}
}
.el-tree {
background: transparent;
color: #c0cbe0;
margin-right: 10px;
/deep/.is-current {
background: #13386c;
> .el-tree-node__content {
background: #13386c;
}
}
.span-ellipsis {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 16px;
font-weight: bold;
}
.el-tree-node__content:hover {
background-color: rgba(20, 57, 109, 0.3);
}
.el-tree-node {
.is-current {
background-color: #13386c;
}
}
.el-tree-node {
.is-leaf + .el-checkbox .el-checkbox__inner {
display: inline-block;
border: 1px solid #489fff;
background-color: #3242654d;
}
.el-checkbox .el-checkbox__inner {
display: none;
border: 1px solid #489fff;
background-color: #3242654d;
}
}
.el-tree-node:focus > .el-tree-node__content {
background-color: #13386c;
}
.el-tree-node__label {
font-size: 16px;
font-weight: bold;
}
.el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #409eff;
}
}
}
</style>
6、总结
这个组件通过 el-tree
组件展示树形结构设备列表,支持节点点击、展开、过滤等功能,并通过多种方法和事件与父组件进行交互。数据通过后端接口获取并动态更新树结构,具有良好的用户体验和扩展性。