‘自己’这个东西是看不见的,,撞上一些别的什么,反弹回来,才会了解自己。

功能效果速览:

输入form表单项(时间区间)==> 生成table对应的列名

本功能主要是实现【新建自定义配置】,输入配置基本信息,可以自由添加、删除 输入多个‘时间区间’。输入完成后点击确定,对应生成表格,如:输入时间区间(0-1,1-2,2-3)表格中的列就是(序号、核素、0-1,1-2,2-3,总释放量)输入时间区间(0-1,1-2,2-3,3-4,4-5,5-6)表格中的列就是(序号、核素、0-1,1-2,2-3,3-4,4-5,5-6,总释放量)

element table 动态设置高度 elementui表格动态列_vue.js

效果说明:

1. el-form-item动态添加行 删除行操作 ==> 实现输入需要多少个的表格列

element table 动态设置高度 elementui表格动态列_前端_02

2. el-table动态加载el-form-item输入的列名称 ==> 输入多少个列名,动态生成多少个列的表格,并可以自由编辑。

element table 动态设置高度 elementui表格动态列_vue.js_03

3.el-table根据后端返回数据回显动态表格el-table

element table 动态设置高度 elementui表格动态列_前端_04


目录

功能效果速览

 一、实现el-form动态增减表单项

1.基础功能form表单

2.el-form动态增减表单项的修改使用

(1)添加addDomain

(2)删除deleteDomain()

(3)确认提交-生成表格列数据

 二、根据列数组动态生成表格

1.完成固定列表格

2.动态生成列dynamicColumns

2.获取填写表格数据

3.按照接口要求拼接前端数据

 三、查看列表数据回显

1. 获取后端返回数据

2.拼接重组前端数据


 一、实现el-form动态增减表单项

1.基础功能form表单

为了方便,将表单分成两个写,第一个没有难度,附代码。

element table 动态设置高度 elementui表格动态列_el-table_05

<el-form :inline="true" :model="paramsForm">
        <el-row>
          <el-col :span="8">
            <el-form-item label="配置名称:">
              <el-input
                v-model="paramsForm.name"
                placeholder="请输入"
                style="height: 32px"
                size="mini"
              ></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="设施名称:">
              <el-select
                v-model="paramsForm.facilityId"
                placeholder="请选择"
                size="mini"
              >
                <el-option label="CEFR堆" :value="1"> </el-option>
                <el-option label="CARR堆" :value="2"> </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="采集时间:">
              <el-date-picker
                value-format="yyyy-MM-dd HH:mm:ss"
                v-model="paramsForm.collectTime"
                type="datetime"
                size="mini"
                placeholder="选择日期时间"
              >
              </el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

2.el-form动态增减表单项的修改使用

Element - The world's most popular Vue UI framework

element table 动态设置高度 elementui表格动态列_javascript_06

 我们按照这个逻辑写一下我们的输入,只不过我们是两个Input。其中时间区间这一项需要绑定paramsForm的times

<el-form-item
            v-for="(time, index) in paramsForm.times"
            :label="'时间区间' + (index * 1 + 1) + ':'"
            :key="time.key"
            :prop="'time.' + index + 1"
          >
            <el-input
              v-model="time.start"
              placeholder="请输入"
              style="height: 32px; width: 100px"
              size="mini"
              type="number"
              min="0"
            ></el-input>
            <span style="margin: 0px 20px">--</span>
            <el-input
              v-model="time.end"
              placeholder="请输入"
              style="height: 32px; width: 100px"
              size="mini"
              min="0"
              type="number"
            ></el-input>
            <span style="margin: 0px 20px">Hour</span>
            <i
              class="el-icon-circle-close"
              style="color: red"
              @click.prevent="removeDomain(time)"
            ></i>
            <i
              class="el-icon-circle-plus-outline"
              style="margin: 0px 20px"
              v-if="index == paramsForm.times.length - 1"
              @click.prevent="addDomain()"
            ></i>
          </el-form-item>
// data中的数据声明
paramsForm: {
        name: "",
        times: [{ start: "", end: "", key: "1" }],
},

  另外,需要补充两个函数:添加(addDomain())删除(removeDomain(item))

(1)添加addDomain

思路:向parmsForm数组push一个元素,为了区分,key值设置成了时间,其中start,end为起始时间终止时间

// 添加区间
    addDomain() {
      console.log("添加区间", this.paramsForm.times);
      this.paramsForm.times.push({
        start: "",
        end: "",
        key: Date.now(),
      });
      console.log("after", this.paramsForm.times);
    },

 (2)删除deleteDomain()

// 删除执行函数
    removeDomain(item) {
      var index = this.paramsForm.times.indexOf(item);
      if (index !== -1) {
        this.paramsForm.times.splice(index, 1);
      }
    },

(3)确认提交-生成表格列数据

timeSubmit() {
      console.log(this.paramsForm);
      // 不调接口-暂时保存区间-用于生成table
      this.dynamicColumns = [];
      this.paramsForm.times.forEach((e) => {
        let item = e.start + "-" + e.end + "Hours";
        this.dynamicColumns.push({ prop: item, label: item });
      });
      console.log(this.dynamicColumns, "动态列数据");
      // 页面切换
      this.page = 1;
    },

// dynamicColumns: "",
// page: 0, //页面显示0-显示新增列额面1-表格页面

element table 动态设置高度 elementui表格动态列_vue.js_07

element table 动态设置高度 elementui表格动态列_el-table_08

 页面控制切换到table页面,至此完成页面page=0。可以看到,dynamicColumns动态列为我们为后续准备好的动态列表数组!!!!包含label和prop属性。

element table 动态设置高度 elementui表格动态列_vue.js_09

 二、根据列数组动态生成表格

1.完成固定列表格

element table 动态设置高度 elementui表格动态列_vue.js_10

<el-table
        :data="tableData"
        width="100%"
        max-height="calc( 100vh - 380px )"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="序号" prop="index" width="55" align="center">
          <template slot-scope="scope">
            <span>{{ scope.$index + 1 }}</span>
          </template>
        </el-table-column>
        <el-table-column label="核素" prop="name" align="center">
          <template slot-scope="scope">
            <el-select
              v-model="scope.row.name"
              placeholder="请选择"
              v-if="isEdit"
              size="mini"
              filterable
            >
              <el-option
                v-for="item in hsSelectOption"
                :key="item.name"
                :label="item.name"
                :value="item.name"
              >
              </el-option>
            </el-select>
            <span v-else>{{ scope.row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column>
          核心--动态部分列
        </el-table-column>
        <el-table-column prop="sum" label="总释放量" align="center">
          <template slot-scope="scope">
            <el-input
              v-if="isEdit"
              v-model="scope.row.sum"
              autocomplete="off"
              size="mini"
            ></el-input>
            <span v-else> {{ scope.row.sum }}</span>
          </template>
        </el-table-column>
      </el-table>

2.动态生成列dynamicColumns

 动态列生成思路:el-table-colum进行循环遍历dynamicColumns中元素。动态绑定prop属性值。表格头部使用slot="header"绑定lable显示列名称。

对于表格中每一个元素的值,使用scope.row[item.prop]绑定!!!!

<el-table-column
          v-for="(item, index) in dynamicColumns"
          :key="index"
          :prop="item.prop"
        >
          <template slot="header">
            {{ item.label }}
          </template>
          <template slot-scope="scope">
            <!-- {{ scope.row.custom[item.prop] }} -->

            <el-input
              v-if="isEdit"
              v-model="scope.row[item.prop]"
              autocomplete="off"
              style="width: 100px"
              size="mini"
            ></el-input>
            <span v-else>{{ scope.row[item.prop] }}</span>
          </template>
        </el-table-column>

2.获取填写表格数据

<div class="saveButton">
        <el-button type="primary" plain size="mini">取消</el-button>
        <el-button type="primary" size="mini" @click="finalSave"
          >保存</el-button
        >
</div>

使用finalSave()函数。首先输出tableData数组,也就是我们填写好的表格数据,可以看到无误。

element table 动态设置高度 elementui表格动态列_el-table_11

finalSave() {
      console.log("保存前的table数据:", this.tableData);
      // 前端拼接格式保存数据
      let data = {};
      for (let i = 0; i < this.tableData.length; i++) {
        this.$set(data, this.tableData[i].name, this.tableData[i].sum);
        for (let item in this.tableData[i]) {
          if (item != "name" && item != "sum") {
            // 只拼接除了sum和nam的
            let name = this.tableData[i].name + "," + item;
            this.$set(data, name, this.tableData[i][item]);
          }
        }
      }
      console.log(data, "111111111111111111111");
      const params = {
        name: this.paramsForm.name,
        facilityId: this.paramsForm.facilityId,
        collectTime: this.paramsForm.collectTime,
        data: data,
        systemTime: this.parseTime(new Date()),
      };
      console.log("提交参数:", params);
      debugger;
      createReviewOrigin(params).then((res) => {
        if (res.code == 200) {
          console.log(res.data);
          this.$message.success("操作成功");
          this.$parent.changePage();
          this.$parent.getOriginList();
        }
      });
    },

3.按照接口要求拼接前端数据

后端需要的数据结构如下:

data = {
    Ac-2232: "10"
    Ac-2232,0-1Hours: "1"
    Ac-2232,1-2Hours: "2"
    Ac-2232,2-3Hours: "3"
    Ac-2232,3-4Hours: "4"

    Am-237: "26"
    Am-237,0-1Hours: "5"
    Am-237,1-2Hours: "6"
    Am-237,2-3Hours: "7"
    Am-237,3-4Hours: "8"
}

 麻烦来啦!!!!我们得到的this.tableData是这样的:

this.tableData = [
 {
    0-1Hours: "1"
    1-2Hours: "2"
    2-3Hours: "3"
    3-4Hours: "4"
    name: "Ac-2232"
    sum: "10"
  },
  {
    0-1Hours: "5"
    1-2Hours: "6"
    2-3Hours: "7"
    3-4Hours: "8"
    name: "Am-237"
    sum: "26"
  }
]

因此,我们使用data保存我们重组的数据,思路:【双层循环遍历】外层遍历tableData的每一项,内层循环遍历tableData的每一列时间数据,然后做拼接操作。

// 前端拼接格式保存数据
      let data = {};
      for (let i = 0; i < this.tableData.length; i++) {
        this.$set(data, this.tableData[i].name, this.tableData[i].sum);
        for (let item in this.tableData[i]) {
          if (item != "name" && item != "sum") {
            // 只拼接除了sum和nam的
            let name = this.tableData[i].name + "," + item;
            this.$set(data, name, this.tableData[i][item]);
          }
        }
      }
      console.log(data, "111111111111111111111");

最后根据接口需要拼接参数发送提交请求。

element table 动态设置高度 elementui表格动态列_前端_12

添加完成后就会看到页面多出来了一条添加的数据‘测试4’

element table 动态设置高度 elementui表格动态列_elementui_13

 三、查看列表数据回显

点击配置名称或者编辑会跳转到查看详情页面。

根据后端的数据==>拼接前端需要的数据==>动态回显列==>回显整个表格。

element table 动态设置高度 elementui表格动态列_vue.js_14

1. 获取后端返回数据

created() {
    // 回显数据
    this.getReviewOrigin();
    // 获取下拉框数据
    this.getFactorList();
  },
methods:{
    // 获取自定义源项列表
    getReviewOrigin() {
      getReviewOrigin(this.dataId).then((res) => {
        this.paramsForm = res.data;
        // 重组表格数据
        this.reformData(res.data.data);
      });
    },
}

// 获取某一自定义源项详情
// export function getReviewOrigin(id) {
//  return request({
//    url: "/data/reviewOrigin/" + id,
//    method: "get"
//  });
//}

获取到的后端数据格式如下:

 

element table 动态设置高度 elementui表格动态列_javascript_15

2.拼接重组前端数据

刚才我们说到从this.tableData重组data数据。现在是逆操作,需要根据data,重组this.tableData数据。

思路:

(1)遍历data,不包含逗号是一个核素,得到核素数组。

element table 动态设置高度 elementui表格动态列_javascript_16

// 拼凑表格数据
    reformData(data) {
      // 1.遍历对象属性=>形成核素对象数组
      let hsData = [];
      let hsItems = [];
      for (let item in data) {
        console.log(item, "=====");
        // 如果item不包含,则是一个核素
        if (!item.includes(",")) {
          hsData.push({ name: item });
          hsItems.push(item);
        }
      }
      console.log(hsData, hsData.length, "组装好的核素");
      // 2.分离出时间段
      let timeData = [];
      this.dynamicColumns = [];
      for (let element in data) {
        if (element.includes(hsData[0].name) && element.includes(",")) {
          timeData.push(element.split(",")[1]);
          this.dynamicColumns.push({
            prop: element.split(",")[1],
            label: element.split(",")[1],
          });
        }
      }
      console.log(timeData, this.dynamicColumns, "分离出的时间区间table列");
      // 3.重组table数据
      let finalData = [];
      for (let i = 0; i < hsData.length; i++) {
        var others = {};
        var form = {};
        let sum = "";
        for (let e in data) {
          console.log("data.e", e, data[e]);

          if (e.includes(hsItems[i]) && e.includes(",")) {
            let name = e.split(",")[1];
            // this.$set(others, name, data[e]);
            this.$set(form, name, data[e]);
            // this.$set(this.levelForm, "dataLevels", isDose ? 2 : 3);
          } else if (e.includes(hsItems[i]) && !e.includes(",")) {
            // this.$set(form, sum, data[e]);
            sum = data[e];
          }
        }
        finalData.push({
          name: hsItems[i],
          sum: sum,
          ...form,
          // others: { "'0-2Hours'": 12, "'2-4Hours'": 34 },
          // others: others,
        });
      }
      console.log(finalData, "0000000000000000000000000000");
      this.tableData = finalData;
    },

(2)遍历取逗号分隔后面的时间部分

element table 动态设置高度 elementui表格动态列_vue.js_17

 (3)重组table数组

element table 动态设置高度 elementui表格动态列_vue.js_18

element table 动态设置高度 elementui表格动态列_elementui_19

<el-table :data="tableData" max-height="450" width="100%">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="序号" prop="index" width="55" align="center">
          <template slot-scope="scope">
            <span>{{ scope.$index + 1 }}</span>
          </template>
        </el-table-column>
        <el-table-column label="核素" prop="name" align="center">
          <template slot-scope="scope">
            <el-select
              v-model="scope.row.name"
              placeholder="请选择"
              v-if="isEdit"
              size="mini"
              filterable
            >
              <el-option
                v-for="item in hsSelectOption"
                :key="item.name"
                :label="item.name"
                :value="item.name"
              >
              </el-option>
            </el-select>
            <span v-else>{{ scope.row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column
          v-for="(item, index) in dynamicColumns"
          :key="index"
          :prop="item.prop"
        >
          <template slot="header">
            {{ item.label }}
          </template>
          <template slot-scope="scope">
            <!-- {{ scope.row.custom[item.prop] }} -->

            <el-input
              v-if="isEdit"
              v-model="scope.row[item.prop]"
              autocomplete="off"
              style="width: 100px"
              size="mini"
            ></el-input>
            <span v-else>{{ scope.row[item.prop] }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="sum" label="总释放量" align="center">
          <template slot-scope="scope">
            <el-input
              v-if="isEdit"
              v-model="scope.row.sum"
              autocomplete="off"
              size="mini"
              style="width: 100px"
            ></el-input>
            <span v-else> {{ scope.row.sum }}</span>
          </template>
        </el-table-column>
      </el-table>