2

一、最终效果:

二、代码:
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
}

llllllllll
7 声望3 粉丝