• antd tree 懒加载+局部刷新


    针对懒加载的树组件,节点数据发生变化后,只刷新局部数据,拿到最新的节点

    思路

     antd tree提供的loadData属性,支持传入一个方法,用于异步加载子节点的数据。当某一节点的数据已经加载之后,收起节点再次展开是不会触发异步加载的方法的,因此节点数据不会刷新。需要我们手动变更一些值才能触发该方法。

    首先要明确树组件触发懒加载的前提条件:

    1. expandedKeys包含节点key值

    2. loadedKeys不包含需要刷新的节点的key值,即此前未曾加载过

    3. treeData中不包含该节点的children数据,即children=[]

    只有以上三点同时满足,才会触发loadData方法。

    方法

    A节点下新增子节点后,刷新A节点的子节点需要3步:

    注意:A节点的所有子孙节点均需要回到收起状态,否则会多次调用接口加载已展开的节点数据

    • 1. loadedKeys中移除A节点的key值和其子孙节点的key值
    • 2. treeData中将A节点的children赋空
    • 3. expandedKeys中移除A节点下的所有子孙节点的key值

    代码:

    1. // 获取当前节点id以及下面所有子孙节点的id
    2. getNodeAndChildrenIds (data) {
    3. let temp = [];
    4. const loop = (data) => {
    5. data.map(item => {
    6. temp.push(item.id)
    7. if (item.children && item.children.length) {
    8. loop(item.children);
    9. }
    10. })
    11. }
    12. loop(data);
    13. return temp;
    14. },
    15. // 更新树组件的数据
    16. updateTreeData(id) {
    17. const temp = _.cloneDeep(this.treeData);
    18. let node;
    19. const loopFn = (data, id) => {
    20. if (node) {
    21. return;
    22. }
    23. data.some((item) => {
    24. if (item.id === id) {
    25. node = _.cloneDeep(item.children);
    26. item.children = [];
    27. return true;
    28. }
    29. if (item.children && item.children.length) {
    30. loopFn(item.children, id);
    31. }
    32. });
    33. };
    34. // 获取A节点的子节点,并把A节点的children移除
    35. loopFn(temp, id);
    36. this.treeData = _.cloneDeep(temp);
    37. // 获取A节点下面所有子孙节点的id
    38. const nodeIds = this.getNodeAndChildrenIds(node);
    39. // loadedKeys中移除A节点的key
    40. let loadedKeys = _.cloneDeep(this.loadedKeys.filter(item => item !== id));
    41. // 去掉A下面已加载的子孙节点的key
    42. loadedKeys = _.cloneDeep(loadedKeys.filter(item => !nodeIds.includes(item)));
    43. this.loadedKeys = _.cloneDeep(loadedKeys);
    44. // 去掉A下面已展开的子孙节点id
    45. this.expandedKeys = _.cloneDeep(this.expandedKeys.filter(item =>
    46. !nodeIds.includes(item)));
    47. }

     以上是刷新子节点的方法。

    当A节点本身发生变更或删除时,则需要刷新A节点的数据,此时同样可以通过上面的方法。但是这里推荐另一种方式,即手动更新数据,不走接口,这种方式更为简单。

    代码:

    1. /** 找到对应的节点执行某操作 */
    2. treeAction (node, id, fn) {
    3. node.some((item,index) => {
    4. if (item.id === id) {
    5. fn(node, item, index)
    6. return true;
    7. }
    8. if (item.children && item.children.length) {
    9. treeAction(item.children, id, fn);
    10. }
    11. });
    12. },
    13. // 删除树节点
    14. async deleteTreeNode(data) {
    15. await api.deleteFn(data.id);
    16. this.$message.success('删除成功!');
    17. // 手动删除A节点和其子孙节点
    18. treeAction(this.treeData, data.id, (node, item, index) => {
    19. node.splice(index, 1);
    20. });
    21. },
    22. // 重命名树节点
    23. async editTreeNode(data, form) {
    24. const params = {
    25. ...
    26. };
    27. await api.editFn(params);
    28. this.$message.success('重命名成功!');
    29. // 手动重置A节点名称
    30. treeAction(this.treeData, data.id, (node, item, index) => {
    31. item.name = form.name;
    32. });
    33. },
  • 相关阅读:
    跨域、跨域问题
    mysql在django中开启事务,实现悲观锁和乐观锁
    JS的事件委托(Event Delegation)
    typescript中高级类型的Record
    聊聊我在腾讯和字节工作感受
    USB Type-C数据线美国新标准UL9990报告检测项目
    使用HTML制作静态网站作业——我的校园运动会(HTML+CSS)
    windows 下载安装 mysql
    速盾:cdn 缓存图片
    使用甘特图来做时间管理
  • 原文地址:https://blog.csdn.net/hfhwfw161226/article/details/127107827