wchbrad / vue-easy-tree

A tree component based on vue2.x that supports a small amount of data or a large amount of data, multiple functions, and virtual scrolling.
MIT License
124 stars 39 forks source link

开启虚拟滚动时,懒加载需要增加node-key么? #3

Closed lele4818 closed 2 years ago

lele4818 commented 2 years ago

开启虚拟滚动时,懒加载我这边测试有问题

<template>
  <div class="ve-tree" style="height:calc(100vh - 20px)">
    <vue-easy-tree
      ref="veTree"
      node-key="id"
      height="calc(100vh - 20px)"
      :props="props"
      lazy
      :load="loadNode"
    ></vue-easy-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      props: {
        label: "name",
        children: "children"
      },
      treeData: []
    };
  },
  created() {

  },
  methods: {
    loadNode(node, resolve) {
      if (node.level === 0) {
        return resolve([{ name: 'region' }]);
      }
      if (node.level > 1) return resolve([]);

      this.getChildrenData(resolve)      
    },
    getChildrenData(resolve) {
      setTimeout(() => {
        const data = [
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },                     
        ]

        resolve(data)
      }, 1000)
    }    
  }
};
</script>

<style>
</style>

image

wchbrad commented 2 years ago

你好,虚拟滚动下是支持懒加载的,根据你的代码,我将 `<vue-easy-tree ref="veTree" node-key="id" height="calc(100vh - 20px)" :props="props" lazy :load="loadNode"

改为 <vue-easy-tree ref="veTree" node-key="name" height="calc(100vh - 20px)" :props="props" lazy :load="loadNode" ` 即可,区别在于虚拟滚动下需要指定node-key,且node-key必须全tree唯一

wchbrad commented 2 years ago

按照你的代码逻辑,loadNode方法中: if (node.level > 1) return resolve([]); 这里是指当节点展开级别在一级以上(不含第一级)时,返回空,所以第二级肯定展开为空了。你可以将这里的级别设定大一点,比如: if (node.level > 2) return resolve([]); 你就能看到第二级的节点展开了

lele4818 commented 2 years ago

按照你的代码逻辑,loadNode方法中: if (node.level > 1) return resolve([]); 这里是指当节点展开级别在一级以上(不含第一级)时,返回空,所以第二级肯定展开为空了。你可以将这里的级别设定大一点,比如: if (node.level > 2) return resolve([]); 你就能看到第二级的节点展开了

是的 我刚发现我的代码写的有问题。改了下能够展开了 请问下你有对el-tree源码的异步加载的代码逻辑作修改或者做特殊处理吗?

lele4818 commented 2 years ago

修改后能够正常异步展开的代码 感谢作者大佬的解答 (所以关键是node-key吗)

<template>
  <div class="ve-tree" style="height:calc(100vh - 20px)">
    <vue-easy-tree
      ref="veTree"
      node-key="name"
      height="600px"
      :props="props"
      lazy
      :load="loadNode"
    ></vue-easy-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      props: {
        label: "name",
        children: "children"
      },
      treeData: []
    };
  },
  created() {

  },
  methods: {
    loadNode(node, resolve) {
      if (node.level === 0) {
        return resolve([{ name: 'region' }]);
      }
      if (node.level >= 1) {
        this.getChildrenData(resolve)  
      };    
    },
    getChildrenData(resolve) {
      setTimeout(() => {
        const data = [
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },                     
        ]

        resolve(data)
      }, 1000)
    }    
  }
};
</script>

<style>
</style>
wchbrad commented 2 years ago

按照你的代码逻辑,loadNode方法中: if (node.level > 1) return resolve([]); 这里是指当节点展开级别在一级以上(不含第一级)时,返回空,所以第二级肯定展开为空了。你可以将这里的级别设定大一点,比如: if (node.level > 2) return resolve([]); 你就能看到第二级的节点展开了

是的 我刚发现我的代码写的有问题。改了下能够展开了 请问下你有对el-tree源码的异步加载的代码逻辑作修改或者做特殊处理吗?

针对虚拟滚动,我对整个展开逻辑(包括非懒加载)增加了特殊处理以增加性能,有兴趣可以查阅源码

wchbrad commented 2 years ago

修改后能够正常异步展开的代码 感谢作者大佬的解答 (所以关键是node-key吗)

<template>
  <div class="ve-tree" style="height:calc(100vh - 20px)">
    <vue-easy-tree
      ref="veTree"
      node-key="name"
      height="600px"
      :props="props"
      lazy
      :load="loadNode"
    ></vue-easy-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      props: {
        label: "name",
        children: "children"
      },
      treeData: []
    };
  },
  created() {

  },
  methods: {
    loadNode(node, resolve) {
      if (node.level === 0) {
        return resolve([{ name: 'region' }]);
      }
      if (node.level >= 1) {
        this.getChildrenData(resolve)  
      };    
    },
    getChildrenData(resolve) {
      setTimeout(() => {
        const data = [
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },
          {
            name: Math.random(),
          },                     
        ]

        resolve(data)
      }, 1000)
    }    
  }
};
</script>

<style>
</style>

关键确实是node-key,我觉得可能需要在文档里增加说明,感谢使用