一、最终效果:
二、代码:
1.vue文件
<template>
<div>
<Row>
<Col span="24">
<Input
prefix="ios-search"
v-model="searchName"
clearable
placeholder="请输入名称"
@on-enter="searchTree"
/>
</Col>
<Col span="24">
<Tree :data="treeData" @on-select-change="selectChange"></Tree>
</Col>
</Row>
</div>
</template>
<script>
import { listToTree } from "../../../libs/listToTree.js";
export default {
data() {
return {
treeRawData: [
//后端返回的数据
{ title: "地球", id: "1", parentId: "0" },
{ title: "中国", id: "2", parentId: "1" },
{ title: "上海", id: "3", parentId: "2" },
{ title: "徐汇", id: "4", parentId: "3" },
{ title: "美国", id: "5", parentId: "1" },
{ title: "纽约", id: "6", parentId: "5" },
],
treeData: [], //前端处理后的数据
searchName: "", //输入框绑定的数据
currentId: "", //需要选中的节点id
};
},
mounted() {
this.treeData = listToTree(this.treeRawData); //将后端返回的list数据转化为树结构
},
methods: {
//输入节点名称后按回车健搜索
searchTree() {
let exist = false;
for (var i = 0; i < this.treeRawData.length; i++) {
if (this.treeRawData[i].title.indexOf(this.searchName) !== -1) {
//在树中存在
exist = true;
this.currentId = this.treeRawData[i].id;
/*需要重新获取treeRawData,不然会出现这种情况:数据是对的,但是视图渲染不出来,导致没有搜索结果*/
this.treeRawData = [
{ title: "地球", id: "1", parentId: "0" },
{ title: "中国", id: "2", parentId: "1" },
{ title: "上海", id: "3", parentId: "2" },
{ title: "徐汇", id: "4", parentId: "3" },
{ title: "美国", id: "5", parentId: "1" },
{ title: "纽约", id: "6", parentId: "5" },
];
this.treeData = listToTree(this.treeRawData);
/*需要重新获取treeRawData,不然会出现这种情况:数据是对的,但是视图渲染不出来,导致没有搜索结果*/
this.treeData = this.fineCurrentIdRecursive(this.treeData);
break;
} else if (!exist && i === this.treeRawData.length - 1) {
//在树中不存在
this.$Message.error("无搜索结果");
}
}
},
//通过节点id选中树中节点并展开它的父节点-递归方式
fineCurrentIdRecursive(list) {
for (var i = 0; i < list.length; i++) {
if (list[i].id === this.currentId) {
list[i].selected = true; //如果节点id等于currentId,则选中该节点
break;
} else {
if (list[i].children && list[i].children.length > 0) {
list[i].children = this.fineCurrentIdRecursive(list[i].children); //找不到想要的节点则继续找孩子的(递归)
for (var j = 0; j < list[i].children.length; j++) {
if (list[i].children[j].selected || list[i].children[j].expand) {
list[i].expand = true; //如果子节点(末端节点)选中或者子节点(非末端节点)展开,则展开该子节点的父节点
break;
}
}
}
}
}
return list;
},
// 点击节点文字展开收起
selectChange(data, selectedNode) {
this.$set(selectedNode, "expand", !selectedNode.expand);
}
}
};
</script>
2.引入的listToTree.js文件
//将后端返回的list数据转化为树结构
export const listToTree = (list) => {
var arr = []
let items = {}
var idsStr = ''
// 获取每个节点的直属子节点(是直属,不是所有子节点)
for (let i = 0; i < list.length; i++) {
let key = list[i].parentId
if (items[key]) {
items[key].push(list[i])
} else {
items[key] = []
items[key].push(list[i])
}
idsStr += idsStr === '' ? list[i].id : ',' + list[i].id
}
for (var key in items) {
if (idsStr.indexOf(key) === -1) {//找到最大的父节点key
arr=formatTree(items, key)
}
}
delete arr[0].parentId
return arr
}
function formatTree(items, parentId) {
let result = []
if (!items[parentId]) {
return result
}
for (let t of items[parentId]) {
t.children = formatTree(items, t.id)//递归获取children
result.push(t)
}
return result
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。