zoukankan      html  css  js  c++  java
  • tree 的节点懒加载

    1. 在实际项目开发中,当 tree 的某个节点大于 2000 个时,dom 渲染起来就非常慢,整个页面就会卡了起来.
    2. 基于 vue elementUI 来开发,用到了 InfiniteScroll 无限滚动 Tree 树形控件
    3. 来个 demo,具体看下 tree 子节点过多时的卡顿吧。
    1. 优化思路就是 前端刚开始只加载 10 个子节点,当滚动到底部时,再增加 10 个。
    <div id="app">
      <div
        class="tree-box1"
        :infinite-scroll-immediate="false"
        v-infinite-scroll="load"
      >
        <el-tree
          :data="curList"
          v-loading="loading"
          default-expand-all
          :props="defaultProps"
          @node-click="handleNodeClick"
        ></el-tree>
      </div>
    </div>
    <style>
      .tree-box1 {
        height: 200px;
        overflow: auto;
      }
    </style>
    
    <script>
      var Main = {
        data() {
          return {
            loading: false,
            curtreePageSize: 10,
            allList: [],
            curList: [],
            defaultProps: {
              children: 'children',
              label: 'label',
            },
          }
        },
        methods: {
          //滚动轴滚动最底部触发,tree的数组动态增加
          load() {
            if (this.allList.length) {
              console.log('滚动')
              this.curtreePageSize += 10
              this.curList = this.sliceTree(this.allList, this.curtreePageSize)
            }
          },
          handleNodeClick(data) {
            console.log(data)
          },
          //tree数组的截取,默认截取10个,可以动态配置
          sliceTree(data, len = 10) {
            return [
              {
                label: '一级 1',
                children: data.slice(0, len),
              },
            ]
          },
          // 这是模拟跟后端的请求;用setTimeout模拟
          impersonationRequest() {
            this.loading = true
            let arr = []
            for (let i = 1; i < 4000; i++) {
              arr.push({ label: `二级 1-${i}` })
            }
            setTimeout(() => {
              this.allList = arr
              this.curList = this.sliceTree(this.allList)
              this.loading = false
            }, 1000)
          },
        },
        mounted() {
          this.impersonationRequest()
        },
      }
      var Ctor = Vue.extend(Main)
      new Ctor().$mount('#app')
    </script>
    
    1. 好了基本完结,假如你不用el-tree自带的关键字过滤树节点的话。
      又或者后端大佬愿意帮你写个接口,返回过滤后的tree给你;
      不然的话,你就自己来实现了。el-tree本身的过滤是没有问题的,但是你用了懒加载,例如只加载了10个,它只会在你10个里面来进行搜索;你就需要自己写个算法来实现;
      核心代码如下
    /**
     * data 为 tree数据
     * name 为 筛选关键词
     **/
    const filterTree  = (data, name) => {
               // 当name数据为空时,返回默认的10个数据dom
               if (!name) {
                   this.curList = this.sliceTree(this.allList)
                   return
               }
               const PrimaryNode = [...data] //数组
               // 递归的方法,来判断
               function traverse (node) {
                   node.forEach(v => {
                       //假如当前节点的属性满足 关键词,则将当前节点的visible属性设置为tree
                       v.visible = v.label.includes(name)
                       //如果纯在子节点,就递归调用本函数
                       if (v.children) {
                           traverse(v.children)
                       }
                       /* 当前节点visible为false, 且有子节点的再判断一次
                        假如子节点存在visible为true,则父节点的visible也设置成tree
                        这个涉及到递归的执行顺序问题,我们假如搜索的孙子节点三级,
                        const tree = [{
                           label:'一级',
                           children:[{
                               label: '二级',
                               children:[{
                               label: '三级',
                               }]
                           }]
                       }]
                       下面代码执行顺序是从最深处开始执行,然后渐渐到外层的,所以不会有问题;
                       */
                       if (!v.visible && v.children) {
                           v.visible = v.children.some(child => child.visible)
                       }
                   })
               }
               //第二个函数的作用,就是过滤掉visible为false的选项。比较容易理解
               function filterName (node) {
                   const newNode = node.filter(v => v.visible)
                   newNode.forEach(v => {
                       if (v.children) {
                           v.children = filterName(v.children)
                       }
                   })
                   return newNode
               }
               traverse(PrimaryNode)
               const filterNode = filterName(PrimaryNode).slice(0,100)
               if(filterNode.length) {
                  this.curList = [{
                     label: '一级 1',
                     children: filterNode
                     }] 
               }else {
                 this.curList = []
               }
           },
    
  • 相关阅读:
    Excel教程(5)
    Excel教程(4)
    Excel教程(3)
    Excel教程(2)
    如何在Excel中少犯二(I)
    for zip
    temp
    study
    eclipse
    shell
  • 原文地址:https://www.cnblogs.com/taxi/p/14190370.html
Copyright © 2011-2022 走看看