vxe-grid控件树状展示的性能测试

vxe-table的表格功能强,性能高,支持虚拟滚动和懒加载。我在工作中用到i-view的表格和hui的表格,在数据量大,尤其是树状而且数据量大时,加载展示很缓慢。这里准备将需要大屏展示的表格替换成vxe-grid(vxe-grid是vxe-table的高级版本,支持动态自定义列)来使用。

gitee地址: https://gitee.com/xuliangzhan_admin/vxe-table

文档地址:https://xuliangzhan_admin.gitee.io/vxe-table/#/table/api

测试的性能文件记录如下:

1. 新建html文件,引入vue和vxe-table的相关cdn文件:

  <!-- 引入vue -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  <!-- 引入样式 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vxe-table/lib/style.css">
  <!-- 引入脚本 -->
  <script src="https://cdn.jsdelivr.net/npm/xe-utils"></script>
  <script src="https://cdn.jsdelivr.net/npm/vxe-table"></script>

2. 新建treeTable.js文件,封装vxe-grid组件,将是否懒加载、节点数、子节点数封装成对外接口。

  props: {
    // 是否懒加载
    ifLazy: {
      type: Boolean,
      default: false
    },
    // 节点数(最外层)
    nodeCount: {
      type: Number,
      default: 1000
    },
    // 最外层节点上的每个节点的子节点数
    childrenCount: {
      type: Number,
      default: 10
    }
  }

表格数据在proxy-config属性中获取。懒加载时,需要配置的属性如下:

children

树子节点的属性

 

lazy

是否使用懒加载(需要配合 hasChild )

 

hasChild

只对 lazy 启用后有效,标识是否存在子节点,从而控制是否允许被点击

 

loadMethod

该方法用于异步加载子节点(必须返回 Promise<any[]> 对象)

3. 在父节点中使用treeTable.js中定义的子组件,且挂载在dom中。

完成的效果图:

完整代码如下:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>查看表格效率</title>
  <!-- 引入vue -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  <!-- 引入样式 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vxe-table/lib/style.css">
  <!-- 引入脚本 -->
  <script src="https://cdn.jsdelivr.net/npm/xe-utils"></script>
  <script src="https://cdn.jsdelivr.net/npm/vxe-table"></script>
</head>
<body>
  <div>
    <div id="tablContent"></div>
  </div>
  <script src="./treeTable.js"></script>
  <script>
    let vueParent = new Vue({
      el: '#tablContent',
      template: `
      <div>
      <p>{{ifLazy?"懒加载":"完全加载"}}耗时({{nodeCount}}*{{childrenCount}}子节点):{{costTime}}毫秒</p>
      <vxeTable :ifLazy="ifLazy" :nodeCount="nodeCount" :childrenCount="childrenCount" @onUpdateCost="getCost"></vxeTable>  
      </div>
      `,
      components: {
        'vxeTable': vxeTable
      },
      data() {
        return {
          ifLazy: true,
          nodeCount: 100,
          childrenCount: 100,
          costTime: 0
        }
      },
      methods: {
        getCost(value){
          this.costTime = value
        }
      }
    })
  </script>
</body>
</html>

treeTable.js:

let vxeTable = {
  template: `
    <vxe-grid
    border
    resizable
    height="400"
    :proxy-config="tableProxy"
    :columns="tableColumn"
    :tree-config="treeConfig"></vxe-grid>
  `,
  props: {
    ifVirtualScroll: {
      type: Boolean,
      default: false
    },
    // 是否懒加载
    ifLazy: {
      type: Boolean,
      default: false
    },
    // 节点数(最外层)
    nodeCount: {
      type: Number,
      default: 1000
    },
    // 最外层节点上的每个节点的子节点数
    childrenCount: {
      type: Number,
      default: 10
    }
  },
  data () {
    return {
      // 用于记录加载前的时间
      beginTime: undefined,
      // 数据代理
      tableProxy: {
        ajax: {
          // 查询根节点
          query: () => {
            return this.getDatas(this.nodeCount, this.ifLazy?0:this.childrenCount, true)
          }
        }
      },
      // 自定义列格式
      tableColumn: [
        { field: 'id', title: 'ID', width: 200, treeNode: true },
        { field: 'name', title: '名称', width: 100},
        { field: 'size', title: '大小', width: 100 },
        { field: 'createTime', title: '创建时间'},
        { field: 'updateTime', title: '修改时间'}
      ]
    }
  },
  computed: {
    // 配置
    treeConfig(){
      return this.ifLazy ?  
      {
        lazy: true, 
        children: 'children', 
        hasChild: 'hasChild', 
        loadMethod: this.loadChildrenMethod
      }:
      {}
    }
  },
  methods: {
    // 生成数据,以promise格式返回
    getDatas(dataCount, childrenCount=0, hasChild= false) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          let _data = []
          for(let i=0; i<dataCount; i++) {
            let _item = 
              {
                id: i,
                name: '名称',
                size: 100,
                createTime: new Date(),
                updateTime: new Date(),
                children: []
              }
            if(!this.ifLazy && childrenCount) {
              for(let j=0; j<childrenCount; j++){
                _item.children.push(
                  {
                    id: i * 10000 +j,
                    name: '子节点名称',
                    size: 200,
                    createTime: new Date(),
                    updateTime: new Date(),
                  }
                )
              }              
            } else if(hasChild){
              _item.hasChild = true
            }
            _data.push(_item)
          }

          // 记录初始时间
          this.beginTime = (new Date()).valueOf();

          // 把数据交给表格
          resolve(_data);

          // 记录加载完成时间
          setTimeout(() => {
            let _endTime = (new Date()).valueOf();
            this.$emit('onUpdateCost', _endTime-this.beginTime);
          }, 0);
        }, 0);
      })
    },
    // 异步加载子节点
    loadChildrenMethod ({ row }) {
      return this.getDatas(this.childrenCount, 0)
    }
  }
}

在我的机器上测试结果:

(ps: 看了下dom,vxe-grid在我设置了height的情况下,并没有自动的给我虚拟滚动呀  😮,原来树状不能与虚拟滚动并存/(ㄒoㄒ)/~~)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
vxe-table中,可以使用vxe-grid组件进行查询操作。具体步骤如下: 1. 在表格中添加vxe-grid组件,并设置其属性和事件。 ```html <vxe-grid ref="grid" :columns="columns" :data="tableData" @query-change="handleQueryChange"></vxe-grid> ``` 其中,columns为表格列的配置,tableData为表格数据,query-change为查询条件改变时的回调函数。 2. 在回调函数中获取查询条件,并根据条件过滤表格数据。 ```javascript methods: { handleQueryChange ({ column, cell, row, rowIndex, $rowIndex, columnIndex, $columnIndex, filters, form }) { const { $table } = this.$refs.grid const { visibleData } = $table const filterList = [] for (const key in filters) { const filter = filters[key] if (filter && filter.length) { filterList.push({ field: key, value: filter[0].value }) } } const filterMethod = ({ row }) => { return filterList.every(({ field, value }) => { return row[field] === value }) } $table.loadData(visibleData.filter(filterMethod)) } } ``` 其中,通过解构赋值获取查询条件,然后根据条件过滤表格数据,并重新加载数据。 3. 在表格中添加查询条件的输入框。 ```html <vxe-toolbar> <vxe-form ref="form" :model.sync="queryForm" :rules="queryRules" :inline="true"> <vxe-form-item label="名称" prop="name"> <vxe-input v-model="queryForm.name" clearable></vxe-input> </vxe-form-item> <vxe-form-item label="年龄" prop="age"> <vxe-input v-model="queryForm.age" clearable></vxe-input> </vxe-form-item> <vxe-form-item> <vxe-button type="primary" @click="$refs.grid.commitProxy('query')">查询</vxe-button> <vxe-button @click="$refs.grid.commitProxy('reset')">重置</vxe-button> </vxe-form-item> </vxe-form> </vxe-toolbar> ``` 其中,queryForm为查询条件的数据模型,queryRules为查询条件的校验规则,$refs.grid.commitProxy('query')为触发查询操作的方法,$refs.grid.commitProxy('reset')为触发重置操作的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值