ElementUi el-tree动态加载节点数据 load方法触发机制

需求背景:需要根据点击后获取的数据动态渲染一个 el-tree,同时渲染出来的 el-tree,需要点击节点时才能获取该节点的层数的获取,如图所示,我需要点击“组”节点才能渲染“设备列表”树,同时“设备列表”树的节点,在我点击具体节点时才能获取具体层数,也就是获取点击节点的数据

请添加图片描述
源代码:

/** html */
<el-dialog :title="dialog.title" v-model="dialog.visible" width="1200px" append-to-body>
   <el-row :gutter="10">
       <el-col :span="4">
           <el-card shadow="hover">
               <template #header>
                   组:
               </template>
               <el-tree class="mt-2" ref="deptTreeRef" node-key="id" :current-node-key="groupId"
                   :data="instanceGroupTreeOptions" :props="{ label: 'label', children: 'children' }"
                   :expand-on-click-node="false" highlight-current default-expand-all
                   @node-click="handleNodeClickWithGroup">
                   <template #default="{ node, data }">
                       <span class="custom-tree-node">
                           <span>
                               <el-tooltip :show-after="300" :content="data.label" placement="top-start">
                                   <span> {{ ellipsis(data.label, 6) }} </span>
                               </el-tooltip>
                           </span>
                       </span>
                   </template>
               </el-tree>
           </el-card>
       </el-col>
       <el-col :span="4">
           <el-card shadow="hover">
               <template #header>
                   设备列表:
               </template>
               <el-tree class="mt-2" ref="deptTreeRef" :load="loadNode"
                   :props="{ label: 'name', children: 'children', isLeaf: 'leaf' }" lazy
                   :expand-on-click-node="false" @node-click="handleNodeClickWithInstance">
                   <template #default="{ node, data }">
                       <span class="custom-tree-node">
                           <span>
                               <el-tooltip :show-after="300" :content="data.name" placement="top-start">
                                   <span> {{ ellipsis(data.name, 6) }} </span>
                               </el-tooltip>
                           </span>
                       </span>
                   </template>
               </el-tree>
           </el-card>
       </el-col>
   </el-row>

</el-dialog>

/** js */
import type Node from 'element-plus/es/components/tree/src/model/node'
interface Tree {
    name: string,
    leaf?: boolean
}

const dialog = reactive<DialogOption>({
    visible: false,
    title: '点位选择框'
});
const instanceGroupTreeOptions = ref<InstanceGroupTreeVO[]>([]); //组tree data
const node_had = ref<any>() //存储 loadNode 函数中接受的变量
const resolve_had = ref<any>() //存储 loadNode 函数中接受的变量

/** 查询实例组树 */
const getInstanceGroupTree = async () => {
    const res = await treeInstanceGroup(null);
    instanceGroupTreeOptions.value = res.data;
};

/** 查询设备实例列表 */
const getListInstance = async (query: InstanceQuery) => {
    const resData = await listInstance(query);
    instanceList.value = resData.rows;
    instanceList.value.forEach(item => {
        item.name = `${item.name}(${item.type})`
    })
    console.log(instanceList.value)
};

/** 点击 组 树形节点 */
const handleNodeClickWithGroup = async (node: any) => {
    await getListInstance({
        projectId: projectId.value,
        groupId: node.id as string
    })
    //点击 组节点后 通过getListInstance 获取 instanceList(第一层设备列表数据) 渲染设备列表树
    requestNewData()
}

/** 动态加载节点数据函数 */
const loadNode = (node: Node, resolve: (data: Tree[]) => void) => {
    console.log(node)
    //第一步 当node.level 为0时 先存储函数接收的两个变量
    //此处的node.level 为0时 表示的是初始化的节点数据 也就是点击了组节点之后展示的第一层设备列表树的数据 也就是根节点 并不显示在树上
    if (node.level === 0) {
    	//这里将函数接收的两个参数存储起来是将 loadNode手动触发的关键
        node_had.value = node //此处的node 也可以理解为根节点(看不见)
        resolve_had.value = resolve //这里的resolve是根节点的 resolve
        return resolve(instanceList.value) //instanceList 就是点击了组节点之后获取的第一层 设备列表的数据
    }
    //当需要加载节点数据的node type 为bms时 通过接口获取节点数据
    /** 这里再说明一下 点击第一层节点后 渲染的数据还是会调用 loadNode 方法 只不过此时不会走 if (node.level === 0) 这个条件 
     * 此时resolve和node 已经是当前需要加载数据的node 和 resolve
    */
    if (node.data.type == 'bms') {
    	//这段可以修改成你们自己的获取节点数据的接口
        setTimeout(() => {
            resolve(instanceList.value)
        }, 500)
    } else { //如果不是bms则为空 或者以后增加其他条件
        resolve([])
    }
}

/** 获取节点数据 */
const requestNewData = () => {
    node_had.value.childNodes = []; //把存起来的node的子节点清空,不然会界面会出现重复树!这里清空的就是根节点下面的内容
    loadNode(node_had.value, resolve_had.value); //再次执行懒加载的方法
}

onMounted(async () => {
    await getInstanceGroupTree();
});

关于方法的注释都写在代码片段里面了

大概讲一下,首先 loadNode 方法就是 “设备列表” el-tree 上的一个方法,在页面加载时,会立即调用一次,根据代码中的条件去渲染树,接着,点击 “组” 的树节点,触发“组”树节点点击函数,handleNodeClickWithGroup,根据点击的组节点获取对应的组下的设备列表数据,然后执行 requestNewData 函数 从而实现动态渲染,所以loadNode方法是可以手动触发的

另外再说一点,在loadNode中打印出来的node,当node.level == 0 时,我代码注释中所提到的 “根节点” 是我自己理解的意思 就是由这个 node 渲染出后续的子节点 并且这个 所谓的 “根节点” 并不是显示在页面上(不可见)

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值