Vue 复杂json数据在el-table表格中展示(el-table分割数据)

2023-11-16


前言

在做复杂的动态表单,实现业务动态变动,比如有一条需要动态添加的el-form-item中包含了多个输入框,并实现表单验证,但在element-ui组件库中给出的表单校验中没有这样的格式,解决方法可参考文章:Element-UI 实现动态增加多个输入框并校验

如果不想要固定格式的动态增加表单,且增加表单的类型不同,比如按钮开关、文本输入框、数字输入框,想要自由增加不同类型的表单并验证,可以参考文章:Element-UI 实现动态增加多个不同类型的输入框并校验(双重v-for表单验证)

如果还想要还要复制多套表单且可编辑,可以参考文章:Vue 双重v-for渲染表单,再复制表单编辑之深拷贝

表单由输入框、选择器、单选框、多选框等控件组成,动态增加各种编辑框存储格式为json,复制生成另外一套表单存储格式同样为json,不同的是,一条数据包含多个表单,而一个表单包含多个编辑框。

那么一条数据的多套表单在el-table表格该怎么做展示?下文将做讲解。


问题背景

一条复杂的json数据在el-table表格该怎么做展示?

这里有一条数据,json数据最外层有4个数组,也就说一个el-table-column要分割成4个数据,json数据如下:

[
  [
    {
      "key": "screen",
      "val": true,
      "name": "场景开关",
      "sceneType": 1
    },
    {
      "key": "showInterval",
      "val": 0,
      "name": "展示间隔(秒)",
      "sceneType": 2
    },
    {
      "key": "logicManage",
      "val": {
        "id": 5,
        "content": [
          {
            "key": "N",
            "val": "6",
            "name": "N"
          }
        ]
      },
      "name": "逻辑管理",
      "sceneType": 3
    },
    {
      "key": "controlManage",
      "val": [
        {
          "id": 6,
          "content": [
            {
              "key": "showRegions",
              "val": "|214|215|994|995|2163|",
              "name": "展示地区",
              "type": 9
            },
            {
              "key": "showTimeRange",
              "val": [
                [
                  "04:59",
                  "10:59"
                ],
                [
                  "05:13",
                  "20:25"
                ],
                [
                  "00:00",
                  "07:00"
                ]
              ],
              "name": "展示时段",
              "type": 10
            }
          ]
        }
      ],
      "name": "控制管理",
      "sceneType": 4
    },
    {
      "key": "select",
      "val": [
        {
          "id": 1,
          "dayLimits": 0,
          "showProbability": 100,
          "errorProbability": 100
        },
        {
          "id": 2,
          "dayLimits": 0,
          "showProbability": 100,
          "errorProbability": 100
        }
      ],
      "name": "选择",
      "sceneType": 5
    }
  ],
  [
    {
      "key": "screen",
      "val": false,
      "name": "场景开关",
      "sceneType": 1
    },
    {
      "key": "showInterval",
      "val": 0,
      "name": "展示间隔(秒)",
      "sceneType": 2
    },
    {
      "key": "logicManage",
      "val": {
        "id": 5,
        "content": [
          {
            "key": "N",
            "val": "6",
            "name": "N"
          }
        ]
      },
      "name": "逻辑管理",
      "sceneType": 3
    },
    {
      "key": "controlManage",
      "val": [
        {
          "id": 8,
          "content": [
            {
              "key": "isNetwork",
              "val": true,
              "name": "联网",
              "type": 11
            }
          ]
        },
        {
          "id": 1,
          "content": [
            {
              "key": "isFullScreenTrigger",
              "val": true,
              "name": "全屏触发",
              "type": 1
            },
            {
              "key": "triggerRate",
              "val": 30,
              "name": "触发概率(%)",
              "type": 2
            }
          ]
        },
        {
          "id": 4,
          "content": [
            {
              "key": "exchangeRate",
              "val": 30,
              "name": "互换概率(%)",
              "type": 7
            }
          ]
        },
        {
          "id": 5,
          "content": [
            {
              "key": "isFalsePause",
              "val": true,
              "name": "假暂停",
              "type": 8
            }
          ]
        },
        {
          "id": 2,
          "content": [
            {
              "key": "triggerRate",
              "val": 30,
              "name": "触发概率(%)",
              "type": 2
            }
          ]
        }
      ],
      "name": "控制管理",
      "sceneType": 4
    },
    {
      "key": "select",
      "val": [
        {
          "id": 2,
          "dayLimits": 0,
          "showProbability": 100,
          "errorProbability": 100
        },
        {
          "id": 1,
          "dayLimits": 0,
          "showProbability": 100,
          "errorProbability": 100
        },
        {
          "id": 9,
          "dayLimits": 1,
          "showProbability": 100,
          "errorProbability": 100
        }
      ],
      "name": "选择",
      "sceneType": 5
    }
  ],
  [
    {
      "key": "screen",
      "val": true,
      "name": "场景开关",
      "sceneType": 1
    },
    {
      "key": "showInterval",
      "val": 1,
      "name": "展示间隔(秒)",
      "sceneType": 2
    },
    {
      "key": "logicManage",
      "val": {
        "id": 5,
        "content": [
          {
            "key": "N",
            "val": "6",
            "name": "N"
          }
        ]
      },
      "name": "逻辑管理",
      "sceneType": 3
    },
    {
      "key": "controlManage",
      "val": [
        {
          "id": 8,
          "content": [
            {
              "key": "isNetwork",
              "val": true,
              "name": "联网",
              "type": 11
            }
          ]
        }
      ],
      "name": "控制管理",
      "sceneType": 4
    },
    {
      "key": "select",
      "val": [
        {
          "id": 1,
          "dayLimits": 2,
          "showProbability": 100,
          "errorProbability": 100
        }
      ],
      "name": "选择",
      "sceneType": 5
    }
  ],
  [
    {
      "key": "screen",
      "val": false,
      "name": "场景开关",
      "sceneType": 1
    },
    {
      "key": "showInterval",
      "val": 1,
      "name": "展示间隔(秒)",
      "sceneType": 2
    },
    {
      "key": "logicManage",
      "val": {
        "id": 2,
        "content": [
          {
            "key": "N",
            "val": "3",
            "name": "N"
          },
          {
            "key": "interval",
            "val": "5",
            "name": "间隔(秒)"
          }
        ]
      },
      "name": "逻辑管理",
      "sceneType": 3
    },
    {
      "key": "controlManage",
      "val": [
        {
          "id": 5,
          "content": [
            {
              "key": "isFalsePause",
              "val": true,
              "name": "假暂停",
              "type": 8
            }
          ]
        }
      ],
      "name": "控制管理",
      "sceneType": 4
    },
    {
      "key": "select",
      "val": [
        {
          "id": 2,
          "dayLimits": 2,
          "showProbability": 100,
          "errorProbability": 100
        },
        {
          "id": 1,
          "dayLimits": 0,
          "showProbability": 100,
          "errorProbability": 100
        }
      ],
      "name": "选择",
      "sceneType": 5
    }
  ]
]

可以看到,最外层的数据都包含 sceneType ,这个key使用来得知内部数据结构,解析的时候得到sceneType的类型就可以直接解析它内部。

key 是用于数据下发时用到的键,如不需要下发,只是在界面做编辑和展示,可省略。

实现复杂json数据在el-table表格展示

先看实现效果图:

在这里插入图片描述

部分代码如下:

  • 场景开关根据权限来决定是否显示el-switch开关,无权限直接显示文字
  • 多个控制逻辑不做分割,分行显示
<el-table-column label="场景开关" align="center" prop="content">
  <template slot-scope="scope">
    <template>
      <div v-for="(item, index) in scope.row.content" :key="index" class="flex-box self-cell" :style="checkHight(item)">
        <span v-for="(arr, arrIndex) in item" :key="arrIndex">
          <span v-if="arr.sceneType === 1">
            <el-switch v-if="checkPermission(['admin','scene:edit'])" v-model="arr.val" active-color="#409EFF" inactive-color="#F56C6C" @change="changeEnabled(scope.row, arr.val, index, arrIndex)" />
            <span v-else>{{ arr.val ? '开' : '关' }}</span>
          </span>
        </span>
      </div>
    </template>
  </template>
</el-table-column>

<el-table-column label="控制逻辑" align="center" prop="content">
  <template slot-scope="scope">
    <span v-for="(item, index) in scope.row.content" :key="index" class="flex-box self-cell" :style="checkHight(item)">
      <span v-for="(arr, arrIndex) in item" :key="arrIndex">
        <span v-if="arr.sceneType === 4">
          <span v-for="(controlItem, controlIndex) in arr.val" :key="controlIndex">
            <span v-if="controlIndex !== 0"><br></span>
            <span>{{ getName(controlManage, controlItem.id) }}</span>
          </span>
        </span>
      </span>
    </span>
  </template>
</el-table-column>

<el-table-column v-if="columns.visible('content')" label="选择" align="center" prop="content">
  <template slot-scope="scope">
    <div v-for="(item, index) in scope.row.content" :key="index" class="flex-box self-cell" :style="checkHight(item)">
      <span v-for="(arr, arrIndex) in item" :key="arrIndex">
        <span v-if="arr.sceneType === 5">
          <span v-for="(selectItem, selectIndex) in arr.val" :key="selectIndex" class="flex-box-2 self-cell">
            <span>{{ getName(selects, selectItem.id) }}</span>
          </span>
        </span>
      </span>
    </div>
  </template>
</el-table-column>

el-table-column分割线

上面的代码可以看到

  • 第一层v-for写入了 class="flex-box self-cell",用于显示分割线
  • 需要再分割的v-for写入了 class="flex-box2 self-cell",用于显示分割线

如需要动态决定所需分割的列,可用函数动态修改 flex-box,此处不做讲解,只是复制了flex-box命名为flex-box2,并添加属性 min-width: 9999px;,用于显示第二层分割线的长度。

css如下:

  .flex-box {
    align-items: center;
    display: flex;
    height: 60px;
    justify-content: center;
    padding: 0 6px;
  }
  
  .flex-box-2 {
    align-items: center;
    display: flex;
    height: 60px;
    min-width: 9999px;
    justify-content: center;
    padding: 0 6px;
  }

  /deep/ .el-table .el-table__cell.table__cell {
    padding: 0;
  }

  /deep/ .el-table .cell {
    padding: 0 !important;
  }

  /deep/ .el-table .cell .self-cell {
    border-bottom: 1px solid #d3d5d9;
    padding: 6px 5px;
  }

  /deep/ .el-table .cell .self-cell:last-child {
    border-bottom: none;
  }
  

el-table-column高度

第一层v-for还包含 :style="checkHight(item)",用于检测当前行所需要的高度。

从上面的css代码得知,每一行的固定高度为60px,那么,如果分割中的行数再进行分割呢?

分割一次,一条数据的高度应该为120px,如果再分割一次,一条数据的高度为180px,那么就需要写函数来控制。

至于高度应该是多少,还取决于其它列的最高高度。

为什么?先看上面这句话 多个控制逻辑不做分割,分行显示,也就就说控制逻辑高度是不固定的,有多个就换行显示,那么高度动态增加的,不能还是设置60px,效果如图:

在这里插入图片描述

可以看到,第二个分割行的高度不止60px,checkHight()函数实现如下:

checkHight(item) {
  let num1 = 60
  let num2 = 60
  for (var i = 0; i < item.length; i++) {
    if (item[i].sceneType === 4) {
      num1 = item[i].val.length * 30
    }
    if (item[i].sceneType === 5) {
      num2 = item[i].val.length * 60
    }
  }
  return [{
    height: Math.max(num1, num2, 60) + 'px'
  }]
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue 复杂json数据在el-table表格中展示(el-table分割数据) 的相关文章

随机推荐

  • react在不弹出eject的情况下配置sass和antd

    天气越来越热 公司的业务也慢慢放缓 这时候就有空暇时间为自己充点电了 然后就把目标放在了react上 公司的前端技术框架用的是vue 对react早就如雷贯耳 然后自己看了文档就劈里啪啦开始搞 在用create react app脚手架搭建
  • 竞赛 基于RSSI的室内wifi定位系统

    0 前言 优质竞赛项目系列 今天要分享的是 wifi室内定位系统 该项目较为新颖 适合作为竞赛课题方向 学长非常推荐 学长这里给一个题目综合评分 每项满分5分 难度系数 3分 工作量 3分 创新点 4分 更多资料 项目分享 https gi
  • new Date() 日期格式的转换

    let date new Date date getFullYear 获取年份 格式1970年 date getMonth 获取当前年的月份 月份要 1 0代表1月 date getMonth 1 date getDate 获取当前日 1
  • 手写数字识别 (tensorflow==2.4.0)

    import tensorflow as tf from tensorflow import keras fashion mnist keras datasets fashion mnist train images train label
  • 使用jQuery操作input的value值

    表单控件是jQuery的重中之重 因为一旦牵扯到数据交互 就离不开form表单的使用 比如用户的登录注册功能等 在进行操作input的value值的时候 主要使用jQuery的val 方法 点击查看val 的使用方法 看如下代码
  • CGIC文件上传----菜鸟笔记

    CGIC上传文件 一 如何利用CGIC上传自己的文件 原理 当在浏览器点击 提交 表单时候 就会上传文件内容并调用你所编写cgic程序 然后靠cgic代码保存你文件 html代码如下
  • CVPR 2021 Sequential Graph Convolutional Network for Active Learning

    深度学习在计算机视觉方面展现出非常大的进步 其代价是大规模的标注数据集 数据标注是耗时的 需要人工和雇佣成本 在许多领域 数据标注更具挑战性 如医学成像领域 此外 在优化深层神经网络架构时 数据的代表性存在差距 为了克服这些问题 主动学习已
  • HTTP协议之Libcurl

    目录 转载 https www cnblogs com xietianjiao p 13260021 html 一 libcurl简介 二 libcurl的使用 三 libcurl等第三方库的通用编译方法 四 调用libcurl编程访问百度
  • Elasticsearch(八)搜索优化

    Elasticsearch 6 4 2 1 理解字段分析过程 一个常被问到的问题是 为什么指定的文档没有被搜索到 很多情况下 这都归因于映射的定义和分析例程的配置存在问题 针对分析过程的调试 Elasticsearch提供了专用的REST
  • h5py存取简例

    当数据太大 好像是 gt 2G scipy io savemat 会报错 考虑换用 h5py 这种格式 matlab 也可以读 见 4 Code import numpy as np import h5py a np arange 12 r
  • SiamMask 测试程序分析

    之前分析了 DaSiamRPN 的测试代码 侧重于执行细节 到了 SiamMask 似乎主题应该有所升华 故事的明线为跟踪器构成 暗线为训练流图 相比于 DaSiamRPN SiamMask 不仅网络结构是现代化的 系统设计也更具匠心 这便
  • MATLAB——参数根轨迹的绘制

  • C# 接口(Interface)

    简介 接口定义了所有类继承接口时应遵循的语法合同 接口定义了属性 方法和事件 这些都是接口的成员 接口只包含了成员的声明 成员的定义是派生类的责任 接口提供了派生类应遵循的标准结构 接口使得实现接口的类或结构在形式上保持一致 抽象类在某种程
  • 双fifo流水线实现3x1024数组数据按列相加

    Vivado版本 2019 2 MATLAB Modelsim版本 Modelsim SE 64 10 7 实验内容 双fifo流水线实现3x1024数组数据按列相加 FIFO First Input First Output 既先入先出
  • 小程序 云函数中file转base64

    mp4文件转base64 云函数中下载文件 const res await cloud downloadFile fileID fileID const base64 data video mp4 base64 res fileConten
  • 计算机编程语言:解释型语言与编译型语言的理解

    一 计算机编程语言 主要分为3类 高级语言 抽象层次更高的便于记忆和表示的英文代码 汇编语言 抽象层次较高的对应机器硬件的cpu指令集 英文缩的助记 符号代码 机器语言 抽像层次最低的由0 1序列所表示的机器码 计算机底层只能识别0 1 所
  • TIMIT数据集无法打开?sph格式转换为wav

    打开TIMIT数据集发现提示无法打开文件 上网搜索发现文件虽然后缀是WAV 但是其实是sph格式 是无法打开的 需要转换为wav 找到一种python方法转换格式 但是不知道为什么sphfile库下载安装了就是无法引用 然后又找到了一个ma
  • Linux 安装Zookeeper

    Linux 安装Zookeeper 下载 wget https mirrors tuna tsinghua edu cn apache zookeeper zookeeper 3 4 14 解压 tar zxvf zookeeper 3 4
  • qt学习笔记2:信号和槽

    信号和槽 实现点击按钮关闭窗口 按钮 gt 点击 gt 窗口 gt 关闭 connect 信号的发送者 发送的具体信号 信号的接收者 信号的处理 信号的处理就是槽 一个是信号的发送方 一个是信号的接收方 信号槽有一个优点 松散耦合 即发送方
  • Vue 复杂json数据在el-table表格中展示(el-table分割数据)

    文章目录 前言 问题背景 实现复杂json数据在el table表格展示 el table column分割线 el table column高度 前言 在做复杂的动态表单 实现业务动态变动 比如有一条需要动态添加的el form item