El-table 懒加载表格中新增、删除遇到的问题

news2024/11/26 14:37:27

前言

我是用的版本是:
在这里插入图片描述
官方给的例子中只是一个单纯的展示,但实际需求中可能会有一些其他需求,比如新增、修改。
然后遇到了各种问题,因此记录一下。

记录

:tree-props="{ children: 'children', hasChildren: 'hasChildren' }",先说一下配置
从下图可以看到,懒加载方法只执行了一次。当你手动闭合再重新展开后并没有重新执行懒加载方法。
懒加载的判断是:

  • hasChildren为true,有小箭头,有小箭头才有加载的前提
  • 有加载前提后,再判断children有没有值,无值则执行

最开始时由于子级是没有数据的,因此展开时执行了懒加载;当子数据有值后,就不会再执行懒加载。

注意:这里是手动闭合再展开,而不是执行懒加载代码,这个后面会用到。
在这里插入图片描述

问题1

const loadTreeData = (row, treeNode, resolve) => {
    console.log('执行懒加载了');
    // setTimeout 相当于执行查询接口
    setTimeout(() => {
        const data = [
            {
                id: 2,
                date: '2023-07-02',
                name: 'no_2',
                address: '上海',
                children: [],
                hasChildren: false
            }
        ];
        // 添加父级节点,如果后台返回了父级id(父级id正确),不需要下面的操作
        data.forEach(item => {
            item.parentId = row.id;
        });
        // resolve 必须执行
        resolve(data);
        console.log('数据是:', row);
    }, 1000);
};

这是懒加载方法,正常懒加载执行完,页面上已经显示了子级数据,这时数据也已经变化了,但是确实这样的:可以看到children里面是空的
在这里插入图片描述
解决

 resolve(data);
 row.children = data;
 console.log('数据是:', row);

在这里插入图片描述
这个有什么作用呢?
1、比如说层级,需要递归计算吧,没有数据怎么计算。这里不能后端给,比如你删除了一个数据,层级需要重新计算更新。
2、后面新增时会用到。

问题2

新增的数据不显示,如果没有 row.children = data; 会出现下面的问题
新增了一条数据:1是页面上根本没有显示出来;2是children里的数据只有新增加的这条
在这里插入图片描述
解决

加上 row.children = data;
在这里插入图片描述

问题3

删除后,tableData里的数据已经删除了,但是页面未更新
在这里插入图片描述
这个比较难处理,你需要在删除后执行一下懒加载方法页面才会更新

定义一个map,将懒加载方法执行时的参数都保存起来

// 定义一个map
const lazyTreeData = new Map();

const loadTreeData = (tree, treeNode, resolve) => {
    console.log('执行懒加载了');
    // 保存参数
    lazyTreeData.set(row.id, [tree, treeNode, resolve]);
    // setTimeout 相当于执行查询接口
    setTimeout(() => {
        const data = [
            {
                id: 2,
                date: '2023-07-02',
                name: 'no_2',
                address: '上海',
                children: [],
                hasChildren: false
            }
        ];
        // 添加父级节点,如果后台返回了父级id(父级id正确),不需要下面的操作
        data.forEach(item => {
            item.parentId = row.id;
        });
        // resolve 必须执行
        resolve(data);
        row.children = data;
        console.log('数据是:', row);
    }, 1000);
};
const delChild = row => {
    // 查找父级节点
    const parent = findParent(tableData.value, row.parentId);
    if (parent) {
        parent.children = parent.children.filter(e => e.id !== row.id);
        console.log('删除后的数据:', tableData.value);
        // 刷新界面
        const [tree, treeNode, resolve] = lazyTreeData.get(row.id);
        loadTreeData(tree, treeNode, resolve);
    }
};

这里存在另一个问题,就是执行懒加载方法时什么时候查询接口,什么时候不查询

// 删除
const delChild = row => {
    // 查找父级节点
    const parent = findParent(tableData.value, row.parentId);
    if (parent) {
        parent.children = parent.children.filter(e => e.id !== row.id);
        console.log('删除后的数据:', tableData.value);
        // 刷新界面
        const [tree, treeNode, resolve] = lazyTreeData.get(parent.id);
        // 记录一下子数据
        newChildren.value = _.cloneDeep(parent.children);
        if (newChildren.value.length == 0) {
            // 如果用户想要全部删除,这时hasChildren设置为false就不会执行懒加载方法
            tableData.value[0].hasChildren = false;
            // 这里要注意,hasChildren = false时只是无箭头了。如果执行loadTreeData,还是会执行的
        } else {
            loadTreeData(tree, treeNode, resolve);
        }
    }
};

// 懒加载方法
const loadTreeData = (row, treeNode, resolve) => {
    console.log('执行懒加载了');
    // 保存参数
    lazyTreeData.set(row.id, [row, treeNode, resolve]);
    // setTimeout 相当于执行查询接口
    if (newChildren.value.length == 0) {
        // 正常的加载数据
        setTimeout(() => {
            const data = [
                {
                    id: 2,
                    date: '2023-07-02',
                    name: 'no_2',
                    address: '上海',
                    children: [],
                    hasChildren: false
                }
            ];
            // 添加父级节点,如果后台返回了父级id(父级id正确),不需要下面的操作
            data.forEach(item => {
                item.parentId = row.id;
            });
            // resolve 必须执行
            resolve(data);
            row.children = data;
            console.log('数据是:', row);
        }, 1000);
    } else {
        // 删除后执行的,用于刷新界面
        resolve(newChildren.value);
        row.children = newChildren.value;
        // 清空newChildren,避免影响其他层级的懒加载
        newChildren.value = [];
    }
};

完整代码及效果

效果
在这里插入图片描述
代码

<template>
    <div>
        <!-- 这里默认不展开全部,如果数据量多的话会有问题 -->
        <el-table :data="tableData" style="width: 100%" row-key="id" border lazy :default-expand-all="false"
            :load="loadTreeData" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
            <el-table-column prop="date" label="Date" />
            <el-table-column prop="name" label="Name" />
            <el-table-column prop="address" label="Address" />
            <el-table-column label="操作">
                <template #default="{ row, $index }">
                    <div>
                        <el-button type="primary" ="addChild(row)">新增</el-button>
                        <el-button type="primary" :disabled="$index == 0" ="delChild(row)">删除</el-button>
                    </div>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import _ from 'lodash';
const tableData = ref([
    {
        id: 1,
        date: '2023-07-01',
        name: 'no_1',
        address: '北京',
        children: [],
        hasChildren: true,
        parentId: -1
    }
]);
// 用于存储懒加载的入参
const lazyTreeData = new Map();
// 用于存储子级数据
const newChildren = ref([]);

// 懒加载方法
const loadTreeData = (row, treeNode, resolve) => {
    console.log('执行懒加载了');
    // 保存参数
    lazyTreeData.set(row.id, [row, treeNode, resolve]);
    // setTimeout 相当于执行查询接口
    if (newChildren.value.length == 0) {
        // 正常的加载数据
        setTimeout(() => {
            const data = [
                {
                    id: 2,
                    date: '2023-07-02',
                    name: 'no_2',
                    address: '上海',
                    children: [],
                    hasChildren: false
                }
            ];
            // 添加父级节点,如果后台返回了父级id(父级id正确),不需要下面的操作
            data.forEach(item => {
                item.parentId = row.id;
            });
            // resolve 必须执行
            resolve(data);
            row.children = data;
            console.log('数据是:', row);
        }, 1000);
    } else {
        // 删除后执行的,用于刷新界面
        resolve(newChildren.value);
        row.children = newChildren.value;
        // 清空newChildren,避免影响其他层级的懒加载
        newChildren.value = [];
    }
};

// 新增方法
const addChild = row => {
    let id = new Date().getTime();
    row.children.push({
        id: id,
        date: new Date().toLocaleString(),
        name: 'no_' + id,
        address: '北京',
        children: [],
        hasChildren: false,
        parentId: row.id
    });
    console.log('新增后的数据:', tableData.value);
};
// 删除
const delChild = row => {
    // 查找父级节点
    const parent = findParent(tableData.value, row.parentId);
    if (parent) {
        parent.children = parent.children.filter(e => e.id !== row.id);
        console.log('删除后的数据:', tableData.value);
        // 刷新界面
        const [tree, treeNode, resolve] = lazyTreeData.get(parent.id);
        // 记录一下子数据
        newChildren.value = _.cloneDeep(parent.children);
        if (newChildren.value.length == 0) {
            // 如果用户想要全部删除,这时hasChildren设置为false就不会执行懒加载方法
            tableData.value[0].hasChildren = false;
        } else {
            loadTreeData(tree, treeNode, resolve);
        }
    }
};

// 递归查找父级
const findParent = (tableData, parentId) => {
    for (let i = 0; i < tableData.length; i++) {
        if (tableData[i].id == parentId) {
            return tableData[i];
        } else {
            if (tableData[i].children) {
                return findParent(tableData[i].children, parentId);
            }
        }
    }
    return undefined;
};
</script>

<style lang="scss" scoped></style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/720566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NumPy怎样使用花式索引或布尔索引访问元素?

除了整数索引之外&#xff0c;NumPy中还提供了两个形式比较复杂的索引——花式索引和布尔索引&#xff0c;下面对这两种索引的基本用法进行详细的讲解。 1.花式索引 花式索引指以整数组成的数组或列表为索引。当使用花式索引访问一维数组时&#xff0c;程序会将花式索引对应的…

音视频基础 - YUV和RGB

1. 音视频名词概念 1.1 像素 像素是一张图片的基础单位&#xff0c;pixel&#xff0c;简称px 无数个像素组合在一起&#xff0c;就形成了一张图片。 1.2 分辨率 分辨率 垂直像素*水平像素&#xff0c;(理论上) 图像的分辨率越高&#xff0c;图像就越清晰。 比如下面左边这张…

【链表OJ】链表的回文结构

⭐️ 往期相关文章 &#x1f4ab;链接1&#xff1a;链表分割 &#x1f4ab;链接2&#xff1a;链表中倒数第k个结点(快慢指针问题) &#x1f4ab;链接3&#xff1a;leetcode 876.链表的中间结点(快慢指针问题) &#x1f4ab;链接4&#xff1a;leetcode 206.反转链表 &#x1f4…

游游画U(秒用c++ string函数)

看到这道题&#xff0c;第一反应是简单的模拟&#xff0c;上手就写&#xff0c;后来看大佬代码&#xff0c;还是我太蠢了 我的&#xff1a; #include <bits/stdc.h> using namespace std; typedef long long LL;int main() {int n;cin>>n;string s ""…

【Spark】RDD转换算子

目录 map mapPartitions mapPartitionsWithIndex flatMap glom groupBy shuffle filter sample distinct coalesce repartition sortBy ByKey intersection union subtract zip partitionBy reduceByKey groupByKey reduceByKey 和 groupByKey 的区别 a…

kafka的broker和replica和文件存储

zookeeper中存储的kafka信息 /brokers/ids&#xff0c;记录存在的服务器id/brokers/topics/test/partitions/0/state&#xff0c;记录leader和可用副本服务器/comsumers&#xff0c;0.9版本之前存储消费者的offset信息&#xff0c;但是会产生zookeeper和broker的跨节点通信/co…

SPSS读取数据文件(一)

1.读取Excel数据文件 &#xff08;1&#xff09;选择“文件”-“打开”-“数据”,在弹出的“打开数据”对话框下选择Excel文件&#xff0c;如图所示 &#xff08;2&#xff09;选择要打开的Excel文件&#xff0c;点击“打开”&#xff0c;如图所示 &#xff08;3&#xff09;可…

[论文总结]YOLO v1、YOLO v2、YOLO v3、YOLO v4、YOLOv5

背景 在这里我们主要介绍YOLO 系列的相关目标检测算法&#xff0c;从最开始的YOLO v1 一直到 YOLO v5。本文也借鉴了其他文档和原始论文。总结下来这五个方法的演进线路如下表格所示。 对比维度YOLO v1YOLO v2YOLO v3YOLO v4YOLO v5backboneVGGdarknet19darknet53darknet53da…

Lua学习笔记:浅谈对垃圾回收的理解

前言 本篇在讲什么 Lua的垃圾回收 本篇适合什么 适合初学Lua的小白 本篇需要什么 对Lua语法有简单认知 依赖Sublime Text编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f…

Unity:sentinel key not found (h0007)

SSD换电脑&#xff0c;unity 编辑器无法打开&#xff1b; 具体步骤&#xff1a; 删除这个路径下的文件 C:\ProgramData\SafeNet 下 Sentinel LDK 打开Windows 的Cmd 命令行&#xff0c;输入编辑器版本下Unity.exe的路径&#xff0c; CD E:\Dev_Env\Unity\Hub\Editor\2020.3.3…

如何将 arduino-esp32 库作为 ESP-IDF 组件使用?

相关文档 arduino-esp32 SDKESP-IDF SDKESP-IDF 软件环境搭建说明Arduino 软件环境使用说明Arduino as an ESP-IDF component &#xff08;官方说明&#xff09; 环境准备 目前&#xff0c;最新 Master 版本的 arduino-esp32 SDK 要求使用 v4.4 版本的 ESP-IDF SDK 软件编译环…

05、Nginx反向代理

一、网关、代理与反向代理&#xff1a; 在Nginx中&#xff0c;网关、代理和反向代理是三种常见的功能&#xff0c;用于转发和处理请求。下面是它们的简要介绍&#xff1a; 网关&#xff08;Gateway&#xff09;&#xff1a; 网关在网络通信中起到中介的作用&#xff0c;将客户…

【视觉SLAM入门】1. 基础知识,运动观测,旋转(旋转矩阵,轴角,欧拉角,四元数)和eigen库基础

"山薮藏疾" 1. 运动与观测1.1 通用运动方程1.2 通用观测方程1.3 对SLAM的认识 2. 三维运动2.1 旋转与平移2.2 变换矩阵2.3 矩阵知识补充2.4 旋转向量2.5 欧拉角2.6 四元数2.7 其他变换 3. 编程基础3.1 链接库说明3.2 eigen库 注&#xff1a; 以后的方程中如未说明&am…

面试官:一千万的数据,要怎么查?

一个老生常谈的问题&#xff0c;SELECT *和SELECT具体字段那个快&#xff1f;在数据量少的时候可能没什么差别&#xff0c;但是数据量达到千万级&#xff0c;差距就显现出来。废话不多说&#xff0c;往下看 ↓。 SELECT * 和 SELECT 具体字段的区别 在 MySQL 中&#xff0c;SE…

批量规范化

✨✨✨ 感谢优秀的你打开了小白的文章 “希望在看文章的你今天又进步了一点点&#xff0c;生活更加美好&#xff01;”&#x1f308;&#x1f308;&#x1f308; 目录 1.批量规范化基本原理 2.批量规范化的使用 2.1对于全连接层 2.2对于卷积层 3.代码实现 3.1方式一 …

26488-24-4,Cyclo(D-Phe-L-Pro),具有良好的生物相容性

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ 【产品描述】 Cyclo(D-Phe-L-Pro)环(D-苯丙氨酸-L-脯氨酸)&#xff0c;环二肽是由两个氨基酸通过肽键环合形成&#xff0c;是自然界中小的环状肽。由于其存在两个酰胺键即四个可以形成氢键的位点&#xff0c;环二肽可以在氢…

商业海外社交媒体营销10步指南 [2023]

如今&#xff0c;社交媒体是任何成功商业战略的重要组成部分。这不是奢侈品&#xff0c;而是必需品。全球有超过 36 亿人使用社交媒体&#xff0c;它是企业展示其产品和服务、建立品牌知名度以及与客户联系的数字游乐场。 但这不仅仅是娱乐和游戏。要在社交媒体上取得成功&…

Golang每日一练(leetDay0114) 矩阵中的最长递增路径、按要求补齐数组

目录 329. 矩阵中的最长递增路径 Longest Increasing Path In A Matrix &#x1f31f;&#x1f31f; 330. 按要求补齐数组 Patching Array &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日…

数据结构--二叉树的性质

数据结构–二叉树的性质 二叉树常考性质 常见考点1: 设非空二叉树中度为0、1和2的结点个数分别为 n 0 、 n 1 和 n 2 &#xff0c;则 n 0 n 2 1 n_0、n_1和n_2&#xff0c;则n_0 n_2 1 n0​、n1​和n2​&#xff0c;则n0​n2​1 n 0 n 2 1 \color{red}n_0 n_2 1 n0​n2​…

图层中大型数据集的分块处理思路

图层中大型数据集的分块处理思路 为改善要素叠加工具&#xff08;如联合和相交&#xff09;的性能和可伸缩性&#xff0c;软件采用了称为自适应细分处理的运算逻辑。当可用的物理内存不足以对数据进行处理时&#xff0c;就会触发系统使用此逻辑。由于保持在物理内存的可用范围…