在vue中实现树形结构的表格,以及对数据结构的处理

发布时间:2024年01月12日

需求:有一些告警数据,如果他们的计划编码相同则实现折叠效果,单击某行数据可以进行关闭,状态发生改变,关闭以后按钮禁用

实现效果:目前所有告警消息都被关闭,如果未被关闭则可以进行关闭

实现代码:

<!--物料管理 -->
<template>
  <div class="app-container">
    <el-table
      v-loading="loading"
      :data="tableList"
      row-key="alarmId"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
    >
      <el-table-column label="计划编码" prop="planCode" />
      <el-table-column label="产品编码" prop="itemCode" />
      <el-table-column label="产品名称" prop="itemName" />
      <el-table-column label="缺少重量" prop="diffValue" />
      <el-table-column label="关闭时间" prop="shutTime" />
      <el-table-column fixed="right" label="操作" width="200">
        <template slot-scope="scope">
          <el-button
            type="text"
            size="small"
            @click="close(scope.row)"
            v-if="scope.row.dealStatus == 0"
            >关闭</el-button
          >
          <el-button
            type="text"
            size="small"
            v-show="scope.row.dealStatus == 1"
            disabled
            >已关闭</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />
  </div>
</template>

<script>
import { alarmList, closeAlarm } from "../../../api/alarm/index";
export default {
  data() {
    return {
      queryParams: {
        pageNum: 1,
        pageSize: 10,
      },
      total: 0,
      loading: false,
      tableList: [],
    };
  },
  created() {
    this.getList();
  },
  methods: {
    async close(row) {
      console.log("参数", row);
      const obj = { alarmId: row.alarmId, dealStatus: 1 };
      const res = await closeAlarm(obj);
      if (res) {
        this.$notify({
          title: "成功",
          message: "该物料告警已被关闭",
          type: "success",
        });
        console.log("关闭成功", res);
        this.getList();
      }
    },
    async getList() {
      const res = await alarmList(this.queryParams);
      if (res) {
        console.log("告警记录", res);
        const newTableList = [];
        res.rows.forEach((item) => {
          const existingItem = newTableList.find(
            (newItem) => newItem.planCode === item.planCode
          );

          if (existingItem) {
            // 如果已存在相同 planCode 的项,将当前项添加到其 children 数组中
            existingItem.children.push({
              alarmId: item.alarmId,
              planId: item.planId,
              planCode: item.planCode,
              itemId: item.itemId,
              itemCode: item.itemCode,
              itemName: item.itemName,
              diffValue: item.diffValue,
              dealStatus: item.dealStatus,
              createTime: item.createTime,
              shutTime: item.shutTime,
              clientIp: item.clientIp,
            });
          } else {
            // 如果不存在相同 planCode 的项,直接添加当前项
            newTableList.push({
              alarmId: item.alarmId,
              planId: item.planId,
              planCode: item.planCode,
              itemId: item.itemId,
              itemCode: item.itemCode,
              itemName: item.itemName,
              diffValue: item.diffValue,
              dealStatus: item.dealStatus,
              createTime: item.createTime,
              shutTime: item.shutTime,
              clientIp: item.clientIp,
              children: [],
            });
          }
        });
        // console.log("告警记录数据结构", newTableList);
        this.tableList = newTableList;
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.callback-btn {
  font-size: 16px;
  font-weight: bold;
  margin-top: 16px;
  color: red;
}
</style>

需要处理的就是表格数据结构,如果后端没有对数据结构进行处理,那我们就要自己处理了

假设这是后端返回的数据结构:

[
    {
        "alarmId": 1,
        "planId": 2,
        "planCode": "DDDDDD1",
        "itemId": 100,
        "itemCode": "CP.021.22.01",
        "itemName": "Sovbond TBBS-80GE(水粉色)",
        "diffValue": 3,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107"
    },
    {
        "alarmId": 2,
        "planId": 2,
        "planCode": "DDDDDD1",
        "itemId": 100,
        "itemCode": "CP.021.22.01",
        "itemName": "Sovbond TBBS-80GE(水粉色)",
        "diffValue": 2,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107"
    },
    {
        "alarmId": 3,
        "planId": 17,
        "planCode": "生产计划2",
        "itemId": 108,
        "itemCode": "CP.040.21.01",
        "itemName": "Sovbond TMTM-80GE",
        "diffValue": 5,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107"
    },
    {
        "alarmId": 4,
        "planId": 17,
        "planCode": "生产计划2",
        "itemId": 108,
        "itemCode": "CP.040.21.01",
        "itemName": "Sovbond TMTM-80GE",
        "diffValue": 4,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107"
    },
    {
        "alarmId": 5,
        "planId": 17,
        "planCode": "生产计划2",
        "itemId": 108,
        "itemCode": "CP.040.21.01",
        "itemName": "Sovbond TMTM-80GE",
        "diffValue": 5,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107"
    },
    {
        "alarmId": 6,
        "planId": 2,
        "planCode": "DDDDDD1",
        "itemId": 101,
        "itemCode": "CP.021.24.01",
        "itemName": "Sovbond TBBS-80GS",
        "diffValue": 2,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107"
    },
    {
        "alarmId": 7,
        "planId": 2,
        "planCode": "DDDDDD1",
        "itemId": 103,
        "itemCode": "CP.023.21.01",
        "itemName": "Sovbond OTOS-80GE",
        "diffValue": 6,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107"
    },
    {
        "alarmId": 8,
        "planId": 15,
        "planCode": "生产计划1",
        "itemId": 732,
        "itemCode": "CP.02",
        "itemName": "美年达",
        "diffValue": 7,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107"
    }
]

而我们需要得到的数据结构是这样的,将planId相同的做成折叠效果,实现方式在上述代码中getList方法中就已经实现了。

[
    {
        "alarmId": 1,
        "planId": 2,
        "planCode": "DDDDDD1",
        "itemId": 100,
        "itemCode": "CP.021.22.01",
        "itemName": "Sovbond TBBS-80GE(水粉色)",
        "diffValue": 3,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107",
        "children": [
            {
                "alarmId": 2,
                "planId": 2,
                "planCode": "DDDDDD1",
                "itemId": 100,
                "itemCode": "CP.021.22.01",
                "itemName": "Sovbond TBBS-80GE(水粉色)",
                "diffValue": 2,
                "dealStatus": 1,
                "createTime": "2024-01-11",
                "shutTime": "2024-01-12",
                "clientIp": "192.168.90.107"
            },
            {
                "alarmId": 6,
                "planId": 2,
                "planCode": "DDDDDD1",
                "itemId": 101,
                "itemCode": "CP.021.24.01",
                "itemName": "Sovbond TBBS-80GS",
                "diffValue": 2,
                "dealStatus": 1,
                "createTime": "2024-01-11",
                "shutTime": "2024-01-12",
                "clientIp": "192.168.90.107"
            },
            {
                "alarmId": 7,
                "planId": 2,
                "planCode": "DDDDDD1",
                "itemId": 103,
                "itemCode": "CP.023.21.01",
                "itemName": "Sovbond OTOS-80GE",
                "diffValue": 6,
                "dealStatus": 1,
                "createTime": "2024-01-11",
                "shutTime": "2024-01-12",
                "clientIp": "192.168.90.107"
            }
        ]
    },
    {
        "alarmId": 3,
        "planId": 17,
        "planCode": "生产计划2",
        "itemId": 108,
        "itemCode": "CP.040.21.01",
        "itemName": "Sovbond TMTM-80GE",
        "diffValue": 5,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107",
        "children": [
            {
                "alarmId": 4,
                "planId": 17,
                "planCode": "生产计划2",
                "itemId": 108,
                "itemCode": "CP.040.21.01",
                "itemName": "Sovbond TMTM-80GE",
                "diffValue": 4,
                "dealStatus": 1,
                "createTime": "2024-01-11",
                "shutTime": "2024-01-12",
                "clientIp": "192.168.90.107"
            },
            {
                "alarmId": 5,
                "planId": 17,
                "planCode": "生产计划2",
                "itemId": 108,
                "itemCode": "CP.040.21.01",
                "itemName": "Sovbond TMTM-80GE",
                "diffValue": 5,
                "dealStatus": 1,
                "createTime": "2024-01-11",
                "shutTime": "2024-01-12",
                "clientIp": "192.168.90.107"
            }
        ]
    },
    {
        "alarmId": 8,
        "planId": 15,
        "planCode": "生产计划1",
        "itemId": 732,
        "itemCode": "CP.02",
        "itemName": "美年达",
        "diffValue": 7,
        "dealStatus": 1,
        "createTime": "2024-01-11",
        "shutTime": "2024-01-12",
        "clientIp": "192.168.90.107",
        "children": []
    }
]

需要值得注意的时候,你已关闭按钮在被关闭时需要使用v-show而不是v-if

因为:

已关闭按钮的 disabled 属性是通过 v-if 条件来控制的。这样的实现方式可能会导致 Vue 在渲染时忽略 disabled 属性,因为在 v-if 的条件下,即使按钮处于已关闭状态,它仍然存在于 DOM 中,只是在用户界面上被隐藏了。

解决这个问题的一种方式是使用 v-show 指令而不是 v-if 来控制按钮的显示与隐藏。v-show 不会在元素隐藏时将其从 DOM 中移除,而是使用 CSS 样式来控制显示和隐藏,这样在已关闭状态下,按钮依然存在于 DOM 中,但用户无法与其交互。

或者将关闭按钮写成这样:

<el-button
  type="text"
  size="small"
  :disabled="scope.row.dealStatus === 1"
>已关闭</el-button>

所以v-showv-if有时候达到的效果可能一样,但也不能乱使用,更何况有时候产生的效果是完全不一样的。

文章来源:https://blog.csdn.net/weixin_56818823/article/details/135544544
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。