如何优雅地处理后端返回的单元格数据

我们需要渲染一个4行3列的表格,我们只需要配置好columns:[{},{},{}],数据dataSource:[{},{},{},{}],当我们columns中对象的属性与dataSource中对象的属性对应时,就可以正常渲染数据啦。但是当我们的后端不是以每行数据进行返回,而是将每个单元格的数据作为一个对象返回时,我们就要自己按行处理数据了。接下来分享一下我的思路。

解题思路: 1、不管后端返回给我们多少条数据,我们只需要明确我们需要的是几行数据,也就是需要定义包含几个对象的数组。 2、根据后端返回每个单元格中的两个字段唯一确定行和列。再根据行列取出对应单元格数据添加到刚才创建的数组中,就可以成功渲染数据了。

具体实现:

  1. 定义tableColumns:我这里的列和行相等,是动态的数据根据num进行遍历渲染得到
js 复制代码
  computed: {
    tableColumns() {
      this.list = []
      let columnsTemp = public_deepCopy(this.columns);
      for (let i = 0; i < this.num; i++) {
        this.list.push({
          title: i + 1,
          dataIndex: i + 1,
          key: i + 1,
          align: 'center',
          scopedSlots: {customRender: i + 1}
        });
      }
      columnsTemp.push(...this.list)
      return columnsTemp
    }
  }
  1. 定义一个函数,用来初始化行,方便处理后端返回的数据
  • 先来看一下后端返回数据格式

我这里的num和sort就可以唯一确定是哪个单元格,num代表行号,sort代表列号

  • 接下来我们开始定义函数初始化行数据
js 复制代码
getArray(arr) {
  // 初始化行,这里根据num的值确定需要几行,创建包含几个对象的空数据
  const rows = Array.from({length: this.num}, () => ({}));
  // 根据num也就是行数-1,确定索引,我们可以知道像一行添加数据,在将sort作为对象的属性名,item作为属性值将数据存储到对应的位置
  arr.forEach(item => {
    rows[item.num - 1][item.sort] = {
      ...item,
      score: item.numerator && item.denominator ? item.numerator + '/' + item.denominator : ''
    };
  });
  // 因为有的单元格没有数据,所以进行判断将空位置填充为null
  rows.forEach(row => {
    for (let i = 1; i <= this.num; i++) {
      if (!row.hasOwnProperty(i)) {
        row[i] = null;
      }
    }
  });
  //最后将处理好的数据返回
  return rows;
},
  • 调接口处理数据
js 复制代码
async queryTemplate() {
  this.loading = true
  const res = await queryWorkAllocationModule({
    moduleId: this.moduleId
  });
  this.loading = false;
  if (res.state === 200) {
    this.dataSource = this.getArray(res.data);
  } else {
    this.$message.error(res.message)
  }
},
  • 处理好的数据结构就是这样啦,这样就可以跟我们上面定义的tableColumns数组包含的对象属性进行一一对应了
  • 渲染数据
js 复制代码
<a-table
    :columns="tableColumns"
    :data-source="dataSource"
    :loading="loading"
    :pagination="false"
    :rowKey="record => record.id"
    bordered
>
  <template slot="headerName">
    <div style="position:relative;width:100px;">
      <div style="text-align: right;">排名</div>
      <div style="text-align: left;">人数</div>
    </div>
  </template>
  <template slot="header" slot-scope="text, record, index">
    {{ index + 1 }}
  </template>
  <template v-for="item in num" :slot="item" slot-scope="text, record, index">
    <a-input v-if="record[item] && commenttype" :key="index"
             v-model="text.score" placeholder="请输入" style="text-align: center;border: none"></a-input>
    <span v-if="record[item] && !commenttype">{{ text.score }}</span>
  </template>
</a-table>
  • 最后放上最终效果图展示

数据处理完成,表格可以正确的被渲染出来了。

相关推荐
Jiaberrr43 分钟前
JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)
前端·javascript·tree·树形·过滤筛选
我码玄黄1 小时前
THREE.js:网页上的3D世界构建者
开发语言·javascript·3d
爱喝水的小鼠2 小时前
Vue3(一) Vite创建Vue3工程,选项式API与组合式API;setup的使用;Vue中的响应式ref,reactive
前端·javascript·vue.js
小晗同学2 小时前
Vue 实现高级穿梭框 Transfer 封装
javascript·vue.js·elementui
WeiShuai2 小时前
vue-cli3使用DllPlugin优化webpack打包性能
前端·javascript
forwardMyLife2 小时前
element-plus的面包屑组件el-breadcrumb
javascript·vue.js·ecmascript
mez_Blog3 小时前
个人小结(2.0)
前端·javascript·vue.js·学习·typescript
珊珊而川3 小时前
【浏览器面试真题】sessionStorage和localStorage
前端·javascript·面试
森叶4 小时前
Electron 安装包 asar 解压定位问题实战
前端·javascript·electron
深情废杨杨4 小时前
前端vue-插值表达式和v-html的区别
前端·javascript·vue.js