[el] form

1. Usage

1. Dynamic form (display form)

The value returned by the backend: the first array is the header, and the rest are the content

      <el-table
            ref="tableHeight"
            :data="tableColumns"
            :height="tableHeight"
            border
            style="width: 100%; margin-top: 1%"
            @row-click="rowclick"
          >
            <el-table-column
              v-for="(item, index) in tableData"
              :key="item.label"
              :prop="item.prop"
              align="center"
              :label="item.label"
            >
              <template slot-scope="scope">
                {
    
    { scope.row[index] }}
              </template>
            </el-table-column>
          </el-table>

          <el-row
            ref="row"
            class="block"
            type="flex"
            justify="end"
            align="middle"
          >
            <el-pagination
              ref="pagination"
              :page-sizes="[10, 30, 50]"
              :current-page.sync="page.page"
              :page-size.sync="page.pagesize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
          </el-row>
<script>
import { mapGetters } from "vuex";
import {
  GetHomeData,
  BpmGetList,
  GetFrom,
  GetFromData,
  AddFromData,
} from "@/api/Bpm";

export default {
  name: "Process",
  computed: {
    ...mapGetters(["userid", "name"]),
  },
  data() {
    return {
      BpmName: {}, //从常用中携带的项目信息
      tableHeight: "0px", //表格高度(有切换status)
      tableData: [], //表头
      tableColumns: [], //表格内容
      tableform: {}, //表格返回的数据之一
      form: {
        appid: 1, //应用编号
        type: 0, //0)待办列表 1)已办列表 2)抄送 3)我发起的
        keyword: "", //关键词
        status: 0, //只在 我的发起时有作用  标签如下 0)草稿 1)流程中 2)已结束
      },
      page: {
        page: 1,
        pagesize: 10,
      },
      total: 50,
    }
  },
   created() {
    this.BpmGetList(this.form);
   },
   methods: {
     // 获取列表
    BpmGetList(form) {
      const a = JSON.parse(localStorage.getItem("Goprocess"));
      this.BpmName = a;
      this.form.appid = this.BpmName.id;
      BpmGetList({
        ...this.page,
        ...form,
        userid: this.userid,
      }).then((res) => {
        this.tableform = res.data;
        this.total = res.data.total;

        // console.log(this.tableform, "列表");
        if (res.data.table) {
          // 表头
          this.tableData = res.data.table[0].map((i, j) => {
            return {
              label: i,
              prop: "a" + [j],
            };
          });
          this.tableColumns = res.data.table.filter(function (
            item,
            index,
            arr
          ) {
            return index != 0;
          });
        }
      });
    },
   }
}
</script>

2. Dynamic form (editable)

The structure returned by the backend: the first array is the table header, and the second is the component corresponding to each cell

My dynamic form is placed in the dynamic form, so there is no data at the beginning. After you need to click Add Row, the corresponding component will appear, and then fill in the data. After clicking the Select button, a form will appear to fill in. The form in this popup is fixed.

As for the table data echo, I don't need it for the time being, so I didn't do it.

If you feel that it is not clear, you can read my other [el] form , which contains the complete code of the dynamic form.

I only write the main code here

<template>
  <div id="SearchHead">
      <el-form-item v-if="item.type == 7" :label="item.name">
            <el-button size="small" @click="addtable(item)" class="addbtn"
              >添加行</el-button
            >
            <el-button size="small" @click="deletetable(item)" class="Cancelbtn"
              >删除</el-button
            >
            <el-table
              ref="table"
              :data="item.table1"
              border
              style="width: 100%; margin-top: 1%"
              :header-cell-style="{
                padding: '0',
              }"
              @selection-change="handleSelectionChange"
            >
              <el-table-column type="selection" width="45" align="center">
              </el-table-column>
              <el-table-column
                type="index"
                label="序号"
                width="50"
                align="center"
              >
              </el-table-column>
              <el-table-column
                v-for="(i, index) in item.table"
                :key="i.label"
                :prop="i.prop"
                align="center"
                :label="i.label"
              >
                <template slot-scope="scope">
                  <!-- <div v-if="scope.row[index] instanceof Object ? true : false"> -->
                  <el-input
                    size="small"
                    v-if="scope.row[index].type === 0"
                    v-model="scope.row[index].default_val"
                    placeholder="请输入"
                  ></el-input>
                  <el-input-number
                    size="small"
                    v-if="scope.row[index].type === 1"
                    v-model="scope.row[index].default_val"
                    placeholder="请输入"
                  ></el-input-number>
                  <el-select
                    size="small"
                    v-if="scope.row[index].type === 2"
                    v-model="scope.row[index].default_val"
                    placeholder="请选择"
                  >
                    <el-option
                      v-for="(i, ind) in scope.row[index].attr"
                      :key="ind"
                      :label="i"
                      :value="i"
                    >
                    </el-option>
                  </el-select>
                  <el-date-picker
                    size="small"
                    v-if="scope.row[index].type === 3"
                    v-model="scope.row[index].default_val"
                    type="date"
                    placeholder="选择日期"
                    format="yyyy-MM-dd"
                  >
                  </el-date-picker>
                  <el-date-picker
                    size="small"
                    v-if="scope.row[index].type === 4"
                    v-model="scope.row[index].default_val"
                    type="datetime"
                    placeholder="选择日期时间"
                  >
                  </el-date-picker>
                  <el-radio-group
                    v-if="scope.row[index].type === 5"
                    v-model="scope.row[index].default_val"
                  >
                    <el-radio
                      :label="ii"
                      v-for="ii in scope.row[index].attr"
                      :key="ii"
                      >{
    
    { ii }}</el-radio
                    >
                  </el-radio-group>
                  <el-checkbox-group
                    v-if="scope.row[index].type === 6"
                    v-model="scope.row[index].default_val"
                  >
                    <el-checkbox
                      :label="jj"
                      v-for="jj in scope.row[index].attr"
                      :key="jj"
                    ></el-checkbox>
                  </el-checkbox-group>
                  <el-upload
                    v-if="scope.row[index].type === 8"
                    action="#"
                    :class="{
                      hide: scope.row[index].attr.length === 1 ? true : false,
                    }"
                    name="file_name"
                    :http-request="
                      (file, fileList) =>
                        http(file, fileList, scope.row, 'wenjian', index)
                    "
                    :limit="1"
                    :show-file-list="true"
                    :file-list="scope.row[index].attr"
                    :on-change="
                      (file, fileList) =>
                        handlechange(
                          file,
                          fileList,
                          scope.row,
                          'wenjian',
                          index
                        )
                    "
                    :on-remove="
                      (file, fileList) =>
                        Remove(file, fileList, scope.row, 'wenjian', index)
                    "
                  >
                    <el-button
                      :class="{
                        hide: scope.row[index].attr.length === 1 ? true : false,
                      }"
                      icon="el-icon-upload2"
                      style="width: 100%; text-align: left"
                      size="small"
                      class="dashedbtn"
                      >上传文件</el-button
                    >
                  </el-upload>
                  <el-select
                    size="small"
                    filterable
                    v-if="scope.row[index].type === 9"
                    v-model="scope.row[index].default_val"
                    placeholder="请选择"
                  >
                    <el-option
                      v-for="(i, ind) in scope.row[index].attr"
                      :key="ind"
                      :label="i.name"
                      :value="i.name"
                    >
                    </el-option>
                  </el-select>
                  <el-popover
                    append-to-body
                    ref="editPopover"
                    placement="right-end"
                    width="750"
                    trigger="manual"
                    v-model="scope.row[index].show"
                    v-if="scope.row[index].type === 10"
                    :reference="prevTarget"
                    :key="popperFlag"
                  >
                    <div>
                      <el-button
                        size="small"
                        class="addbtn"
                        @click="add(scope.row[index])"
                        >添加行</el-button
                      >
                      <el-button
                        size="small"
                        class="addbtn"
                        @click="sub(scope.row[index])"
                        >保存</el-button
                      >
                      <el-button
                        size="small"
                        class="addbtn"
                        @click="cancel(scope.row[index])"
                        >取消</el-button
                      >
                    </div>
                    <el-table
                      border
                      height="45vh"
                      style="width: 100%; margin-top: 10px"
                      :data="scope.row[index].attr"
                    >
                      <el-table-column
                        align="center"
                        property="date"
                        label="检测标准"
                      >
                        <template slot-scope="sco">
                          <el-select
                            style="width: 100%"
                            filterable
                            v-model="sco.row.standard"
                            multiple
                            placeholder="请选择"
                            @change="changeStandard"
                            value-key="id"
                          >
                            <el-option
                              v-for="item in standardoptions"
                              :key="item.value"
                              :label="item.no"
                              :value="item"
                            >
                            </el-option>
                          </el-select>
                        </template>
                      </el-table-column>
                      <el-table-column
                        align="center"
                        property="name"
                        label="检测项目"
                      >
                        <template slot-scope="sco">
                          <el-select
                            style="width: 100%"
                            filterable
                            v-model="sco.row.item"
                            multiple
                            placeholder="请选择"
                            @focus="onfocus(sco.row)"
                          >
                            <el-option
                              v-for="item in itemoptions"
                              :key="item.id"
                              :label="
                                item.name + '(' + item.projecttypename + ')'
                              "
                              :value="
                                item.name + '(' + item.projecttypename + ')'
                              "
                            >
                            </el-option>
                          </el-select>
                        </template>
                      </el-table-column>
                      <el-table-column
                        width="60"
                        property="name"
                        label="操作"
                        align="center"
                      >
                        <template slot-scope="sco">
                          <el-button
                            type="text"
                            @click="del(scope.row[index].attr, sco.$index)"
                            >删除</el-button
                          >
                        </template>
                      </el-table-column>
                    </el-table>
                    <el-button
                      type="text"
                      slot="reference"
                      @click="showPopover(scope.row[index], $event)"
                      >选择</el-button
                    >
                  </el-popover>
                  <!-- </div>
                  <div v-else>
                    <el-input
                      size="small"
                      v-model="scope.row[index]"
                      placeholder="请输入"
                    ></el-input>
                  </div> -->
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>
  </div>
</template>

<script>
import axios from "axios";
import { UploadData } from "@/api/Equipment";
import { mapGetters } from "vuex";
import { GetParameterListById, GetAllStandardList } from "@/api/Basic";

export default {
  name: "SearchHead",
  computed: {
    ...mapGetters(["userid", "name", "btnsUrl", "token"]),
  },
  props: {
    List: [Object, Array],
  },
  data() {
    return {
      multipleSelection: [], //多选
      tableFormrules: [],
      tableForm: {},
      ta: [],
      fileList: [], //文件列表
      formData: new FormData(),
      up: [],
      url: "", //项目类别的地址
      standardoptions: [], //检测标准的列表
      itemoptions: [], //检测项目的列表
      ids: "", //检测标准id的集合
      tablevisible: false, //检测标准和项目的弹出框
      prevTarget: null, // 编辑 Popover 的 Reference (参照),用于 popover.js 对齐两个元素
      popperFlag: false, // 用于编辑 Popover 的刷新
    };
  },
  mounted() {
    // 表格中的产品名称的数据(因为是根据后端返回的地址进行调用接口的,就是第一张图events中的地址))
    this.List.dom.forEach((i, j) => {
      if (i.type === 7) {
        // 工装夹具
        if (i.attr[1].length > 0) {
          i.attr[1].forEach((ele) => {
            // 下拉框(项目类别)
            if (ele.type === 9) {
              if (ele.events[0].command.substr(0, 10) == "{
    
    {st_url}}") {
                this.btnsUrl.map((obj) => {
                  if (obj.key === "{
    
    {st_url}}") {
                    this.url = ele.events[0].command.replace(
                      /{
    
    {st_url}}/,
                      obj.value
                    );
                    axios({
                      method: "get",
                      url: this.url,
                      // params: {
                      //   name: this.names,
                      // },
                      headers: {
                        token: this.token,
                      },
                    }).then((res) => {
                      ele.attr = res.data.data;
                    });
                  } else {
                    //这里还没做处理,但是和上面是一致的
                    this.url = ele.events[0].command.replace(
                      /{
    
    {url}}/,
                      obj.value
                    );
                  }
                });
              }
            }
          });
        }
      }
    });
    // 弹窗中,检测标准,第一个下拉框的接口
    GetAllStandardList().then((res) => {
      this.standardoptions = res.data;
    });
  },
  created() {},
  methods: {
    // 表格添加行====================================
    addtable(item) {
        var a = [];
        a = item.attr[1].map((obj, idx) => {
          return {
            name: "",
            sort: obj.sort,
            type: obj.type,
            required: obj.required,
            default_val: obj.default_val,
            attr: obj.type === 10 ? [] : obj.attr,
          };
        });
        item.table1.push(a);
      // // 判断表格最后一行是否都填完整
      // if (this.table1.length > 0) {
      //   this.table1[this.table1.length - 1].forEach((item) => {
      //     if (item === "") {
      //       ar = true;
      //     } else {
      //       ar = false;
      //     }
      //   });
      //   if (ar) {
      //     this.$message.error("请将表格填写完整");
      //   } else {
      //     this.table1.push(lis);
      //   }
      // } else {
      //   this.table1.push(lis);
      // }
    },
    // 表格删除
    deletetable(item) {
      var da = [];
      da = item.table1.filter((itemA) => {
        return this.multipleSelection.every((itemB) => {
          return itemB !== itemA;
        });
      });
      item.table1 = da;
      this.multipleSelection = [];
    },
    toggleSelection(rows) {
      if (rows) {
        rows.forEach((row) => {
          this.$refs.table.toggleRowSelection(row);
        });
      } else {
        this.$refs.table.clearSelection();
      }
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },

    // 表格中的导入=====================================
    handlechange(file, fileList, row, col, index) {
      row[index].attr = fileList;
    },
    Remove(file, fileList, row, col, index) {
      row[index].attr = [];
    },
    async http(file, fileList, row, col, index) {
      var formData = new FormData();
      formData.append("files", file.file);
      const res = await UploadData(formData);
      if (res.code === 200) {
        row[index].default_val = res.data[0].FileUrl;
        this.$mess.success("上传成功"); //这个是封装的,无论调用多少次,都只显示一次
      }
    },

    // 检测标准和检测项目======================
    showPopover(row, e) {
      //阻止事件冒泡,兼容ie
      if (event.stopPropagation) {
        event.stopPropagation();
      } else if (window.event) {
        window.event.cancelBubble = true;
      }
      let currentTarget = e.target; // 赋值当前点击的编辑
      // 判断是否需要切换
      if (this.prevTarget === currentTarget) {
        // 同一个元素重复点击
        row.show = !row.show;
      } else {
        // 切换不同元素, 判断之前是否有点击其他编辑 prevTarget
        if (this.prevTarget) {
          // 先清除之前的编辑框
          this.clearEditPopperComponent(row);
          // 然后生成新的编辑框
          this.$nextTick(() => {
            this.prevTarget = currentTarget;
            row.show = true;
          });
        } else {
          // 首次
          // console.log("首次--->this.prevTarget");
          this.prevTarget = currentTarget;
          row.show = true;
        }
      }
    },
    // 清空编辑组件
    clearEditPopperComponent(row) {
      this.prevTarget = null;
      this.popperFlag = !this.popperFlag;
      row.show = false;
    },
    //弹窗中处理第一个下拉框的值,传给后端的是name,但是第二下拉框的接口需要第一个下拉框的id集合
    changeStandard(val) {
      this.ids = [];
      const arr = val.map((i) => {
        return i.id;
      });
      this.ids = arr.toString(",");
    },
    //弹窗中第二个下拉框必须是第一个下拉框有值才能调用接口获取数据
    onfocus(row) {
      if (row.standard.length > 0) {
        GetParameterListById({ standardid: this.ids }).then((res) => {
          this.itemoptions = res.data;
        });
      }
    },
    //弹窗中的添加行
    add(i, index) {
      // console.log(i);
      const ar = {
        standard: [],
        item: [],
        show: false,
      };
      i.attr.push(ar);
    },
    //弹窗中的删除
    del(i, index) {
      i.splice(index, 1);
    },
   //弹窗中的保存
    sub(obj) {
      var nos = [];
      obj.default_val = obj.attr.map((i) => {
        nos = i.standard.map((obj) => {
          return obj.no;
        });
        return {
          standard: nos,
          item: i.item,
        };
      });
      obj.show = !obj.show;
    },
    //弹窗中的取消
    cancel(obj) {
      obj.attr.splice(
        obj.default_val.length,
        obj.attr.length - obj.default_val.length
      );
      obj.show = !obj.show;
    },
  },
};
</script>
<style lang="scss">
#SearchHead {
  width: 100%;
  .el-form-item {
    width: 100%;
  }
  .el-form-item__content {
    width: 100%;
  }
  .el-select {
    width: 100%;
  }
  .el-textarea__inner {
    border: 1px solid #dcdfe6 !important;
  }
  .el-date-editor.el-input {
    width: 100%;
  }
  .el-upload {
    width: 100%;
  }
  .upload {
    .el-upload-list {
      text-align: left !important;
    }
  }
  .hide .el-upload--text {
    display: none !important;
  }
  .el-table__body-wrapper {
    overflow-y: scroll;
  }
}
</style>

3. Dynamic table (merge columns, editable)

Logical sequence: form data addition - add row - select detection standard - detection item - call of product name - add - confirm
Since this form is fixed, the basic data here is fixed, but The display form is still based on dynamics, the same as the above table

When adding a line, judge whether some options in the above form have been selected, and can only be added after being selected;

After the pop-up window appears, first call the interface to obtain the data of the detection standard, then select the standard, then call the interface to obtain the data of the item, call the interface of the product name after the item is selected, and finally click Add

For the complete code, see my other [el] form , I will write the main code here

rowspan method: add the first row of data directly, start from the second row of data, compare it with the previous data, and judge whether it is the same as the serial number of the previous data, if it is the same, it will be 0, if it is not the same, it will be 1 objectSpanMethod method: specify the
merge those columns and rows
<template>
<el-form-item v-if="item.type == 11" :label="item.name">
            <el-button size="small" @click="ad(item)" class="addbtn"
              >添加行</el-button
            >
            <el-button size="small" @click="dele(item)" class="Cancelbtn"
              >删除</el-button
            >
            <el-table
              :ref="'table' + index"
              :data="item.table1"
              border
              :span-method="objectSpanMethod"
              style="width: 100%; margin-top: 1%"
              :header-cell-style="{
                padding: '0',
              }"
              @selection-change="handle"
            >
              <el-table-column type="selection" width="45" align="center">
              </el-table-column>
              <el-table-column
                v-for="i in item.table"
                :key="i.label"
                :prop="i.prop"
                align="center"
                :label="i.label"
              >
                <template slot-scope="scope">
                  {
    
    { scope.row[i.prop] }}
                </template>
              </el-table-column>
              <el-table-column
                type="index"
                label="操作"
                width="120"
                align="center"
              >
                <template slot-scope="scope">
                  <el-button
                    size="small"
                    @click="edit(scope.row, scope.$index, item)"
                    class="addbtn"
                    >编辑</el-button
                  >
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>

  <!-- 添加行的弹窗 -->
    <el-dialog
      :append-to-body="true"
      :title="title"
      :visible.sync="dialogVisible"
      width="80%"
      @close="closetable"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <el-form
        :inline="true"
        :model="ruleForm"
        ref="dynamicValidateForm"
        label-width="100px"
        class="demo-dynamic"
      >
        <el-form-item label="检测标准" prop="jcbz">
          <el-select
            v-model="ruleForm.jcbz"
            placeholder="请选择检测标准"
            filterable
            value-key="id"
            @change="Standard"
          >
            <el-option
              v-for="item in standardoptions"
              :key="item.id"
              :label="item.no"
              :value="item"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="检测项目" prop="jcxm">
          <el-select
            v-model="ruleForm.jcxm"
            placeholder="请选择检测项目"
            filterable
            value-key="id"
            @focus="focus()"
            @change="jcxm"
          >
            <el-option
              v-for="item in itemoptions"
              :key="item.id"
              :label="item.name"
              :value="item"
            >
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>

      <el-button size="small" @click="diaAdd()" class="addbtn">添加</el-button>
      <el-button size="small" @click="diaDele()" class="Cancelbtn"
        >删除</el-button
      >
      <el-table
        :data="all1"
        style="width: 100%; margin-top: 10px"
        border
        @selection-change="diaHandle"
      >
        <el-table-column type="selection" width="45" align="center">
        </el-table-column>
        <el-table-column
          v-for="(i, index) in all"
          :key="i.label"
          :prop="i.prop"
          align="center"
          :label="i.label"
        >
          <template slot-scope="scope">
            <el-input
              size="small"
              v-if="scope.row[index].type === 0"
              v-model="scope.row[index].default_val"
              placeholder="请输入"
            ></el-input>
            <el-input-number
              size="small"
              v-if="scope.row[index].type === 1"
              v-model="scope.row[index].default_val"
              placeholder="请输入"
            ></el-input-number>
            <el-date-picker
              size="small"
              v-if="scope.row[index].type === 3"
              v-model="scope.row[index].default_val"
              type="date"
              placeholder="选择日期"
              format="yyyy-MM-dd"
            >
            </el-date-picker>
            <el-date-picker
              size="small"
              v-if="scope.row[index].type === 4"
              v-model="scope.row[index].default_val"
              type="datetime"
              placeholder="选择日期时间"
            >
            </el-date-picker>
            <el-select
              size="small"
              filterable
              v-if="scope.row[index].type === 9"
              v-model="scope.row[index].default_val"
              placeholder="请选择"
            >
              <el-option
                v-for="(i, ind) in scope.row[index].attr"
                :key="ind"
                :label="i.name"
                :value="i.name"
              >
              </el-option>
            </el-select>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closetable()">取 消</el-button>
        <el-button type="primary" @click="sure()">确 定</el-button>
      </span>
    </el-dialog>
</template>

<script>
import axios from "axios";
import { mapGetters } from "vuex";
import {
  GetTypeListById,
  GetParameterListById,
  GetAllStandardList,
  GetStandardListById,
} from "@/api/Basic";
import { Time } from "@/utils/index";

export default {
  name: "SearchHead",
  computed: {
    ...mapGetters(["userid", "name", "btnsUrl", "token"]),
  },
  props: {
    List: [Object, Array],
  
  },
  data() {
    return {
      multipleSelection: [], //多选
      tableFormrules: [],
      tableForm: {},
      standardoptions: [], //检测标准的列表
      itemoptions: [], //检测项目的列表
      ids: "", //检测标准id的集合
      ite: {}, //产品大类的选择
      it: "", //资质
      ie: "", //参数
      im: [], //产品名称(产品类别)

      all: [],
      all1: [],
      dialogVisible: false,
      arr: {}, //弹窗所需的当前表格信息
      ruleForm: { jcbz: "", jcxm: "" },
      spanArr: [],
      position: 0,
      editnum: 1,
      row: {},
      multiple: [],
      title: "新增",
    };
  },
  watch: {
    List: {
      handler(newVal, oldVal) {
        if (JSON.stringify(newVal) !== "{}") {
          this.ne();//处理数据
        }
      },
      immediate: true, // //immediate:true代表如果在 wacth 里声明了之后,就会立即先去执行里面的handler方法,如果为 false,不会在绑定的时候就执行。
      // deep: true, //默认值是 false,代表是否深度监听
    },
  },
  methods: {
    // 新测试明细=================================
    ne() {
      this.List.dom.forEach((i, j) => {
        if (i.type === 11) {
          this.all1 = [
            // 需要的类型
            // [
            //   {
            //     sort: 45,
            //     type: 0,
            //     name: "产品名称",
            //     attr: [],
            //     required: false,
            //     default_val: "1",
            //     events: [],
            //   },
            //   {
            //     sort: 46,
            //     type: 0,
            //     name: "商标",
            //     attr: [],
            //     required: false,
            //     default_val: "",
            //     events: [],
            //   },
            //   {
            //     sort: 47,
            //     type: 0,
            //     name: "型号规格",
            //     attr: [],
            //     required: false,
            //     default_val: "",
            //     events: [],
            //   },
            // ],
          ];
          this.all = [
            { label: "产品名称", prop: "a3" },
            { label: "商标", prop: "a4" },
            { label: "型号规格", prop: "a5" },
            { label: "产品编号/批号", prop: "a6" },
            { label: "生产日期", prop: "a7" },
            { label: "数量", prop: "a8" },
            { label: "备注", prop: "a9" },
          ];
          i.table = [
            { label: "序号", prop: "a0" },
            { label: "检测标准", prop: "a1" },
            { label: "检测项目", prop: "a2" },
            { label: "产品名称", prop: "a3" },
            { label: "商标", prop: "a4" },
            { label: "型号规格", prop: "a5" },
            { label: "产品编号/批号", prop: "a6" },
            { label: "生产日期", prop: "a7" },
            { label: "数量", prop: "a8" },
            { label: "备注", prop: "a9" },
          ];
          i.attr = [
            [
              "编号",
              "检测标准",
              "检测项目",
              "产品名称",
              "商标",
              "型号规格",
              "产品编号/批号",
              "生产日期",
              "数量",
              "备注",
            ],
            [
              {
                sort: 42,
                type: 0,
                name: "编号",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 43,
                type: 9,
                name: "检测标准",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 44,
                type: 9,
                name: "检测项目",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 45,
                type: 9,
                name: "产品名称",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 46,
                type: 0,
                name: "商标",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 47,
                type: 0,
                name: "型号规格",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 48,
                type: 0,
                name: "产品编号/批号",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 49,
                type: 3,
                name: "生产日期",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 50,
                type: 1,
                name: "数量",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
              {
                sort: 51,
                type: 0,
                name: "备注",
                attr: [],
                required: false,
                default_val: "",
                events: [],
              },
            ],
          ];
          i.table1 = [
            //需要的形式
            // {
            //   a0: "1",
            //   a1: "YY/T 0520-2009 5.2",
            //   a2: "尺寸",
            //   a3: "个性化基台及螺钉1",
            //   a4: "N/A",
            //   a5: "三边形ANT-R",
            //   a6: "QY2205034",
            //   a7: "2022.05.14",
            //   a8: 5,
            //   a9: "备注",
            // },
          ];
          // 有没有默认值
          if (i.default_val.length > 0) {
            i.default_val.forEach((item, index) => {
              item.cpmc.forEach((n) => {
                i.table1.push({
                  a0: item.no,
                  a1: item.jcbz,
                  a2: item.jcxm,
                  a3: n.cpmc,
                  a4: n.sb,
                  a5: n.ggxh,
                  a6: n.cpbhph,
                  a7: n.scrq,
                  a8: n.sl,
                  a9: n.bz,
                });
              });
            });
          }

          for (let index = 0; index < i.table1.length; index++) {
            this.rowspan(i.table1);
          }
        }
      });
    },
    rowspan(tableData, spanArr, position, spanName) {
      // 每次调用清空数据
      this.spanArr = [];
      this.position = 0;

      tableData.forEach((item, index) => {
        if (index === 0) {
          this.spanArr.push(1);
          this.position = 0;
        } else {
          // 为需要合并查询的项
          if (tableData[index].a0 === tableData[index - 1].a0) {
            this.spanArr[this.position] += 1;
            this.spanArr.push(0);
          } else {
            this.spanArr.push(1);
            this.position = index;
          }
        }
      });
    },
    //合并行列
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (
        columnIndex === 0 ||
        columnIndex === 1 ||
        columnIndex === 2 ||
        columnIndex === 3 ||
        columnIndex === 11
      ) {
        const _row = this.spanArr[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col,
        };
      }
    },
    edit(row, index, item) {
      this.arr = [];
      this.row = {};
      this.title = "编辑";
      this.arr = item; //赋值给this.arr,不能使用json,不然编辑保存的时候没有用
      this.row = JSON.parse(JSON.stringify(row));
      this.editnum = 1;
      const at = JSON.parse(JSON.stringify(item.table1)).filter((i) => {
        if (i.a0 === row.a0) {
          return i;
        }
      });
      this.ruleForm.jcbz = at[0]["a1"];
      this.ruleForm.jcxm = at[0]["a2"];
      // 删除前三个数据
      at.forEach((j) => {
        delete j.a0;
        delete j.a1;
        delete j.a2;
      });
      this.all1 = at;
      const ii = JSON.parse(JSON.stringify(item.table));
      const jj = JSON.parse(JSON.stringify(item.attr[1]));
      ii.splice(0, 3);
      jj.splice(0, 3);

      let ab = [];
      this.all1.filter((ele, ij) => {
        let bt = [];
        bt = jj.map((obj, index) => {
          return {
            name: "",
            sort: obj.sort,
            type: obj.type,
            required: obj.required,
            default_val: ele["a" + (index + 3)],
            attr: obj.type === 10 ? [] : obj.attr,
          };
        });
        ab.push(bt);
      });
      this.all = ii;
      this.all1 = ab;
      this.dialogVisible = true;
    },
    ad(item) {
      // 判断产品大类和报告用章类型是否为空
      let pro = {};
      let baogao = {};
      this.List.dom.forEach((i, j) => {
        if (i.name === "产品大类") {
          pro = i;
        } else if (i.name === "报告用章类型") {
          baogao = i;
        }
      });

      if (pro.default_val === "") {
        this.$message.error("请先填写表单中的产品大类和报告用章类型");
      } else if (baogao.default_val === "") {
        this.$message.error("请先填写表单中的产品大类和报告用章类型");
      } else {
        // 获取产品大类对应的id
        this.ite = pro.attr.find((obj) => {
          return obj.name === pro.default_val;
        });
        const abc = baogao.default_val.filter((ele) => {
          return ele !== "无";
        });

        if (abc.length === 0) {
          this.it = "";
        } else {
          this.it = abc.join(",");
        }

        GetStandardListById({
          productlineid: this.ite.id,
          qualifications: this.it,
        }).then((res) => {
          // console.log(res);
          this.standardoptions = res.data;
        });
        this.arr = [];
        this.all1 = [];
        this.title = "新增";
        this.editnum = 0;
        this.dialogVisible = true;
        this.arr = item;
      }
    },
    dele(item) {
      var da = [];
      da = item.table1.filter((itemA) => {
        return this.multipleSelection.every((itemB) => {
          // console.log(itemB);
          return itemB.a0 !== itemA.a0;
        });
      });
      item.table1 = da;
      this.multipleSelection = [];
      this.$forceUpdate(); //这个是给二级表单用的,二级表单如果不加这个,则数据更新了但是视图没变;而发起新的弹窗则不会出现这个问题,不知道是不是组件嵌套的问题
    },
    handle(val) {
      this.multipleSelection = val;
    },
    // 新测试明细弹窗中的表格操作=================================
    closetable() {
      this.ruleForm = { jcbz: "", jcxm: "" };
      this.all1 = [];
      this.dialogVisible = false;
    },
    Standard(val) {
      this.ids = val.id;
      this.ruleForm.jcxm = "";
      this.ie = "";
      // this.ids = [];
      // const arr = val.map((i) => {
      //   return i.id;
      // });
      // this.ids = arr.toString(",");
    },
    focus() {
      // if (this.ids.length > 0) {
      // console.log(this.ids);
      GetParameterListById({
        standardid: this.ids,
        qualifications: this.it,
      }).then((res) => {
        // console.log(res);
        this.itemoptions = res.data;
      });
      // }
    },
    async jcxm(val) {
      // console.log(val, "jcxm");
      this.ie = val.id;

      // 检测项目选完后调用接口获取产品名称
      const re = await GetTypeListById({
        standardid: this.ids,
        parameterid: this.ie,
      });
      this.im = re.data;
    },
    sure() {
      const b = this.arr.table.map((obj, idx) => {
        return obj.prop;
      });
      // console.log(this.ruleForm);
      // 添加
      if (this.editnum === 0) {
        // 序号
        let num = 0;
        if (this.arr.table1.length > 0) {
          num = Number(this.arr.table1[this.arr.table1.length - 1].a0) + 1;
        } else {
          num = 1;
        }
        var aa = [];
        this.all1.forEach((item, index) => {
          var a = {};
          this.$set(a, b[0], String(num));
          this.$set(a, b[1], this.ruleForm.jcbz.no);
          this.$set(a, b[2], this.ruleForm.jcxm.name);
          for (let index = 0; index < item.length; index++) {
            this.$set(a, b[index + 3], item[index].default_val);
          }
          aa.push(a);
        });
        this.arr.table1.push(...aa);
        this.rowspan(this.arr.table1);
        this.dialogVisible = false;
      } else {
        // 编辑
        // 序号
        const num = this.row.a0;
        var aa = [];
        this.all1.forEach((item, index) => {
          var a = {};
          this.$set(a, b[0], num);
          this.$set(a, b[1], this.ruleForm.jcbz.no);
          this.$set(a, b[2], this.ruleForm.jcxm.name);
          for (let index = 0; index < item.length; index++) {
            this.$set(a, b[index + 3], item[index].default_val);
          }
          aa.push(a);
        });
        // 获取第一个符合条件的下标
        const findIndex = this.arr.table1.findIndex(
          (item) => item.a0 === aa[0].a0
        );
        // 获取所有符合条件的长度
        let nu = 0;
        this.arr.table1.forEach((re, ind) => {
          if (re.a0 === aa[0].a0) {
            nu += 1;
          }
        });
        // 进行替换
        this.arr.table1.splice(findIndex, nu, ...aa);
        this.rowspan(this.arr.table1);
        this.dialogVisible = false;
      }
    },
    async diaAdd() {
      if (this.ruleForm.jcbz !== "" && this.ruleForm.jcxm !== "") {
        let newar = [];
        newar = JSON.parse(JSON.stringify(this.arr.attr[1]));

        if (this.im.length > 0) {
          var a = [];
          newar.splice(0, 3);
          a = newar.map((obj, idx) => {
            return {
              name: "",
              sort: obj.sort,
              type: obj.type,
              required: obj.required,
              default_val: obj.default_val,
              attr: obj.type === 11 ? [] : obj.attr,
            };
          });
          a[0].attr = this.im; //赋值给产品名称
          this.all1.push(a);
        } else {
          this.$message.error("暂无产品名称,请到基础库添加相关信息");
        }
      } else {
        this.$message.error("请先选择检测标准和检测项目");
      }
    },
    diaDele() {
      var da = [];
      da = this.all1.filter((itemA) => {
        return this.multiple.every((itemB) => {
          return itemB !== itemA;
        });
      });
      this.all1 = da;
      this.multipleSelection = [];
      this.$forceUpdate(); //这个是给二级表单用的,二级表单如果不加这个,则数据更新了但是视图没变;而发起新的弹窗则不会出现这个问题,不知道是不是组件嵌套的问题
    },
    diaHandle(val) {
      this.multiple = val;
    },
  },
};
</script>

4. Call the back-end interface to sort the table, click on the page is no longer the current page sorting

Set sortable to custom, listen to the sort-change event on the Table, get the current sorted field name and sort order in the event callback, and set the default sort column and sort order through the default-sort attribute.

<template>
      <el-table
        :data="FieldRecordData"
        :default-sort="{ prop: 'date' }"
        @sort-change="sortchange"
      >
        <el-table-column
          prop="date"
          sortable="custom"
          label="填报日期"
          align="center"
        >
          <template slot-scope="scope">
            {
    
    { scope.row.date | formatDate }}
          </template>
        </el-table-column>
      </el-table>
      <el-row class="block" type="flex" justify="end" align="middle">
        <el-pagination
          :current-page="page.page"
          :page-size.sync="page.pagesize"
          :page-sizes="[10, 20, 30, 40]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="page.total"
          :pager-count="5"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </el-row>
</template>
<script>
import { getRecordsList } from '@/api/FieldRecord'
export default {
  data () {
    return {
      FieldRecordData: [], // 列表数据(展示的数据)
      num: 0,//正序
      page: {
        pagesize: 10,
        page: 1,
        total: 50
      },
    }
  },
  created () {
    this.getlist(0, this.page.page, this.page.pagesize)
  },
  methods: {
    // 排序
    async sortchange (column, prop, order) {
      // 降序
      if (column.order === 'descending') {
        this.getlist(1, this.page.page, this.page.pagesize)
        this.num = 1
      } else if (column.order === 'ascending') {
        this.getlist(0, this.page.page, this.page.pagesize)
        this.num = 0
      } else {
        this.getlist(0, this.page.page, this.page.pagesize)
        this.num = 0
      }
    },
    // 获取数据
    async getlist (num, page, pagesize) {
      const id = this.$route.params.id
      this.loading = true
      const res = await getRecordsList({ page: page, pagesize: pagesize, projectid: id, order: num })
      this.FieldRecordData = res.data.records
      this.page.total = res.data.total
      this.loading = false
    },
    // 分页
    handleSizeChange (Sizechange) {
      this.page.pagesize = Sizechange
      this.getlist(this.num, this.page.page, this.page.pagesize)
    },
    handleCurrentChange (val) {
      this.page.page = val
      this.getlist(this.num, this.page.page, this.page.pagesize)
    }
  }
}
</script>

5、表格的序号为连续

表格使用分页,第一页的序号是1-5,第二页则是6-10,不再从头开始

<el-table-column  :index="CljcMethod"   type="index"    label="序号"    width="50"   align="center"   >
</el-table-column>

 methods: {
         //this.Cljcpage.page是页码,this.Cljcpage.pagesize是一页显示条数
        CljcMethod (index) { return (index + 1) + (this.Cljcpage.page - 1) * this.Cljcpage.pagesize; },
}

6、表格中可编辑的日期选择器设置使用范围

因为是在表格中的选择器,还要进行新增编辑,所以这里的picker-options都定义了两个,一个在data中,一个在methods中获取列表数据的时候。

目标:
1、所有日期都要在总进度的开始日期—实际结束日期之间
2、开始日期:总进度开始日期之后以及包含总进度的开始日期——实际结束日期之前以及包含实际结束日期
3、实际结束日期:与开始日期同理
4、计划结束日期:在当前行的开始日期之后以及包含开始日期——实际结束日期之前以及包含实际结束日期,(若不想包含,则把- 8.64e7去掉即可)

第一张是编辑,需要在获取列表数据的时候就要进行设置使用范围,

  // 获取项目表格数据
    async List () {
      this.da = JSON.parse(localStorage.getItem('ProgressData'))
      const res = await GetSpeed({ projectid: this.da.id })
      res.data.forEach((i, index) => {
        i.plan = {
          disabledDate: (time) => {
            if (i.starttime) {
              return new Date(time).getTime() < new Date(i.starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(res.data[0].endtime).getTime()
            }
          }
        }
        i.end = {
          disabledDate: (time) => {
            if (i.starttime) {
              return new Date(time).getTime() < new Date(i.starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(res.data[0].endtime).getTime()
            }
          }
        }
        i.start = {
          disabledDate: (time) => {
            if (i.plan_endtime) {
              return new Date(time).getTime() > new Date(i.plan_endtime).getTime() || new Date(time).getTime() < new Date(res.data[0].starttime).getTime() - 8.64e7
            }
          }
        }
      })
      this.tableData = res.data

第二张是新增,既是表单,则在data中设置使用范围即可

data () {
    return {
      plan_endtime: {
        disabledDate: (time) => {
          return new Date(time).getTime() < new Date(this.form.starttime).getTime() || new Date(time).getTime() < new Date(this.tableData[0].starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(this.tableData[0].endtime).getTime()
        }
      },
      endtime: {
        disabledDate: (time) => {
          return new Date(time).getTime() < new Date(this.form.starttime).getTime() || new Date(time).getTime() < new Date(this.tableData[0].starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(this.tableData[0].endtime).getTime()
        }
      },
      starttime: {
        disabledDate: (time) => {
          return new Date(time).getTime() > new Date(this.form.plan_endtime).getTime() || new Date(time).getTime() < new Date(this.tableData[0].starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(this.tableData[0].endtime).getTime()
        }
      },
    }
  },

完整代码

<template>
  <div id="pro" class="pro-container">
    <div class="center">
      <div class="top">
        <el-button class="new" type="primary" size="small" @click="Add()"
          >新建节点</el-button
        >
        <div>
          <el-button class="aboutCancel" size="small" @click="home()"
            >返回项目列表</el-button
          >
        </div>
      </div>
      <el-table
        ref="tableData"
        v-loading="loading"
        :cell-style="cellStyle"
        :data="tableData"
        border
        style="width: 100%"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        :header-cell-style="{ 'text-align': 'center' }"
      >
        <el-table-column width="80px" prop="no" label="序号" align="center">
        </el-table-column>
        <el-table-column align="center" prop="name" label="任务名称">
          <template slot-scope="scope">
            <div v-if="scope.row.show">
              <el-input
                v-model="scope.row.name"
                placeholder="请输入"
              ></el-input>
            </div>
            <div v-else>{
    
    { scope.row.name }}</div>
          </template>
        </el-table-column>
        <el-table-column prop="starttime" label="开始日期" align="center">
          <template slot-scope="scope">
            <div v-if="scope.row.show">
              <el-date-picker
                v-model="scope.row.starttime"
                type="date"
                placeholder="选择日期"
                :picker-options="scope.row.start || starttime"
              >
              </el-date-picker>
            </div>
            <div v-else>{
    
    { scope.row.starttime | formatDate }}</div>
          </template>
        </el-table-column>
        <el-table-column
          prop="plan_endtime"
          label="计划结束日期"
          align="center"
        >
          <template slot-scope="scope">
            <div v-if="scope.row.show">
              <el-date-picker
                v-model="scope.row.plan_endtime"
                type="date"
                placeholder="选择日期"
                :picker-options="scope.row.plan || plan_endtime"
              >
              </el-date-picker>
            </div>
            <div v-else>{
    
    { scope.row.plan_endtime | formatDate }}</div>
          </template>
        </el-table-column>

        <el-table-column prop="endtime" label="实际结束日期" align="center">
          <template slot-scope="scope">
            <div v-if="scope.row.show">
              <el-date-picker
                v-model="scope.row.endtime"
                type="date"
                placeholder="选择日期"
                format="yyyy-MM-dd"
                value-format="yyyy-MM-dd"
                :picker-options="scope.row.end || endtime"
              >
              </el-date-picker>
            </div>
            <div v-else>{
    
    { scope.row.endtime | formatDate }}</div>
          </template>
        </el-table-column>
        <el-table-column width="120" prop="day" label="天数" align="center">
          <template slot-scope="scope">
            {
    
    { scope.row.day }}
          </template>
        </el-table-column>
        <el-table-column prop="change_desc" label="时间变动" align="center">
          <template slot-scope="scope">
            <div v-if="scope.row.change_desc === ''">正常</div>
            <div v-else>
              <span>{
    
    { scope.row.change_desc }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column
          width="120"
          prop="state"
          label="项目状态"
          align="center"
        >
          <template slot-scope="scope">
            <div v-show="scope.row.state === 1">未开始</div>
            <div v-show="scope.row.state === 2">进行中</div>
            <div v-show="scope.row.state === 3">延期</div>
            <div v-show="scope.row.state === 4">已结束</div>
          </template>
        </el-table-column>
        <el-table-column width="130px" label="操作" align="center">
          <template slot-scope="scope">
            <div v-if="scope.$index === 0"></div>
            <div v-else>
              <div v-if="scope.row.show" style="display: flex">
                <el-button
                  type="text"
                  @click="change(scope.row, scope.column, scope.$index)"
                  >保存</el-button
                >
                <el-button
                  type="text"
                  @click="cancel(scope.row, scope.column, scope.$index)"
                  >取消</el-button
                >
              </div>
              <div v-else style="display: flex">
                <el-button
                  type="text"
                  :disabled="state"
                  @click="Edit(scope.row, scope.column, scope.$index)"
                  >编辑</el-button
                >
                <el-button
                  type="text"
                  :disabled="state"
                  @click="deleterow(scope.row, scope.column, scope.$index)"
                  >删除</el-button
                >
              </div>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script>
import { GetSpeed, AddSpeed, DeleteSpeed } from '@/api/pro'

export default {
  data () {
    return {
      plan_endtime: {
        disabledDate: (time) => {
          return new Date(time).getTime() < new Date(this.form.starttime).getTime() || new Date(time).getTime() < new Date(this.tableData[0].starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(this.tableData[0].endtime).getTime()
        }
      },
      endtime: {
        disabledDate: (time) => {
          return new Date(time).getTime() < new Date(this.form.starttime).getTime() || new Date(time).getTime() < new Date(this.tableData[0].starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(this.tableData[0].endtime).getTime()
        }
      },
      starttime: {
        disabledDate: (time) => {
          return new Date(time).getTime() > new Date(this.form.plan_endtime).getTime() || new Date(time).getTime() < new Date(this.tableData[0].starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(this.tableData[0].endtime).getTime()
        }
      },
      tableData: [], // 列表数据
      show: false, // 状态
      loading: false, // 加载
      upload: true,
      form: {},//当前行数据
      da: {},//上一页数据
      state: false,
      flagchange: 0, // 表单值是否有改
    }
  },
  created () {
    this.List()
  },
  watch: {
    // 监听编辑是否有修改 - departAddForm
    form: {
      handler (val, oldval) {
        this.flagchange++  // 默认值有变更的话
      },
      deep: true,// 深度监听
    },
  },
  methods: {
    // 获取项目表格数据
    async List () {
      this.loading = true
      this.da = JSON.parse(localStorage.getItem('ProgressData'))
      const res = await GetSpeed({ projectid: this.da.id })
      res.data.forEach((i, index) => {
        i.plan = {
          disabledDate: (time) => {
            if (i.starttime) {
              return new Date(time).getTime() < new Date(i.starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(res.data[0].endtime).getTime()
            }
          }
        }
        i.end = {
          disabledDate: (time) => {
            if (i.starttime) {
              return new Date(time).getTime() < new Date(i.starttime).getTime() - 8.64e7 || new Date(time).getTime() > new Date(res.data[0].endtime).getTime()
            }
          }
        }
        i.start = {
          disabledDate: (time) => {
            if (i.plan_endtime) {
              return new Date(time).getTime() > new Date(i.plan_endtime).getTime() || new Date(time).getTime() < new Date(res.data[0].starttime).getTime() - 8.64e7
            }
          }
        }
      })

      // 重新排序
      res.data.forEach((i, index) => {
        if (index > 0) {
          i.no = 1 + '.' + Number(index)
        }
      })
      this.tableData = res.data
      this.loading = false
    },
    // 编辑
    Edit (row, col, index) {
      this.$set(row, 'show', true)
      this.state = true
      this.form = row
      // 初始化检测数据,取消的时候判断是否修改过值
      this.flagchange = 0
    },
    // 新建
    Add () {
      // 判断上一个有没有保存,保存才添加
      if (!this.state) {
        const index = this.tableData[0].no
        this.form = {
          id: 0,
          no: index + '.' + Number(this.tableData.length),
          projectid: this.da.id,
          name: '',
          starttime: '',
          enddtime: '',
          plan_endtime: '',
          show: true
        }
        this.tableData.push(this.form)
        this.state = true
      } else {
        this.$message({
          type: 'warning',
          message: '请先保存上一任务'
        })
      }
      // 初始化检测数据,取消的时候判断是否修改过值
      this.flagchange = 0
    },
    // 删除
    async deleterow (row, col, index) {
      this.$confirm('是否删除此信息', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        const res = await DeleteSpeed({ speedid: row.id })
        if (res.code === 200) {
          this.$message({
            type: 'success',
            message: '删除成功'
          })
        }
        this.List()
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
      this.form = {}
    },
    // 保存
    async change (row) {
      // 必须全部都写,才会保存
      if (row.name === '' || row.starttime === '' || row.plan_endtime === '' || row.endtime === '') {
        this.$message({
          type: 'warning',
          message: '请填写完整'
        })
      } else {
        row.show = false
        const res = await AddSpeed(this.form)
        if (res.code === 200) {
          this.$message({
            type: 'success',
            message: '保存成功'
          })
        }
        this.List()
        this.state = false
        this.form = {}
      }
    },
    // 取消
    cancel (row) {
      if (row.name === '' || row.starttime === '' || row.plan_endtime === '' || row.endtime === '') {
        row.show = false
        this.List()
      } else {
        if (this.flagchange > 1) { // 说明监听值有变化
          this.$confirm('内容还未保存,是否需要保存', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(async () => {
            const res = await AddSpeed(this.form)
            if (res.code === 200) {
              this.$message({
                type: 'success',
                message: '保存成功'
              })
            }
          }).catch(() => {
            this.$message({
              type: 'info',
              message: '取消保存'
            })
          })
          row.show = false
          this.List()
        } else {
          row.show = false
          this.List()
        }
      }
      this.state = false
      this.flagchange = 0
    },
  
  }
}
</script>

二、样式

1、斑马纹表格(鼠标划过表格,表格颜色不变)

可以通过指定 Table 组件的 row-class-name 属性来为 Table 中的某一行添加 class,表明该行处于某种状态

<el-table
          :row-class-name="tableRowClassName"
          stripe
          :data="tableData"
          style="width: 100%"
        >
          <el-table-column prop="date" label="编号" align="center">
          </el-table-column>
          <el-table-column prop="amount" label="总金额" align="center">
          </el-table-column>
          <el-table-column prop="author" label="创建人" align="center">
          </el-table-column>
</el-table>

方法一

methods: {
    tableRowClassName ({ row, rowIndex }) {
      if (row.sfjg == 1) {
        return "el-table__row--striped";
      } else {
        return "";
      }
    },
    //第二种
     tableRowClassName ({ row, rowIndex }) {
      if (rowIndex % 2 !== 0) {
        return 'el-table__row--striped'
      }
    },
}

方法二

<style lang="scss">
// 显示的颜色
  .el-table--striped .el-table__body tr.el-table__row--striped td {
    background-color: #f2f9ff;
  }
  .el-table__row {
    background: #fff;
  }
  // 鼠标划过表格,表格颜色不变
  .el-table--striped .el-table__body tr.el-table__row--striped:hover td {
    background-color: #f2f9ff;
  }
  .el-table--enable-row-hover .el-table__body tr:hover > td {
    background: #fff;
  }
 
/* 对应第二种方法:表格内背景颜色 */
  .el-table--fit {
    border: 1px solid #64717d;
  }
  .tablewhite {
    background-color: #eef1ff;
  }
  .el-table th > .cell {
    color: #fff;
  }
</style>

2、动态更改某一个单元格字体颜色

通过 :cell-style="cellStyle" 方法返回一个回调

编辑

<el-table
          :row-class-name="tableRowClassName"
          stripe
          :cell-style="cellStyle"
          :data="tableData"
          style="width: 100%"
        >
</el-table>
methods: {
    // 字体颜色
    // row为某一行的除操作外的全部数据
    // * column为某一列的属性
    //  * rowIndex为某一行(从0开始数起)
    // * columnIndex为某一列(从0开始数起
    cellStyle ({ row, column, rowIndex, columnIndex }) {
      // 状态列字体颜色
      if (row.status === 'deleted' && columnIndex === 7) {
        return 'color: red'
      } else if (row.status === 'published' && columnIndex ===7) {
        return 'color: #10bf5d'
      } else {
        return 'color: #1a1a1b'
      }
},
}

3、表格行与行之间留有缝隙

一种是直接在页面中使用

<style lang="scss">
/* 最外层透明 */
#dashboard .el-table,
#dashboard .el-table__expanded-cell {
  background-color: transparent;
}
/* 表格内背景颜色 */
#dashboard .el-table th,
#dashboard .el-table tr,
#dashboard .el-table td {
  background-color: transparent;
}
// 表格单元格的样式
.el-table td.el-table__cell div {
  background-color: #183847;
  border-top: 1px solid #0153bf;
  border-bottom: 1px solid #0153bf;
}
// 第一个单元格的左边框
.el-table td.el-table__cell:first-child div {
  border-left: 1px solid #0153bf;
}
// 最后一个单元格的有边框
.el-table td.el-table__cell:last-child div {
  border-right: 1px solid #0153bf;
}
//el-table既可以滚动又可以自适应
// 表格的滚动条隐藏(table一定要设置行内样式height才有滚动效果,如果还要自适应则设置成height="calc(100%-10rem)")
#dashboard .el-table--scrollable-y ::-webkit-scrollbar {
  display: none;
}
// 头部下方线条长度
#dashboard .el-table__header-wrapper {
  width: 97%;
}
/* 表格内头部 */
#dashboard .el-table th {
  color: #e1e6e9;
  border-bottom: 1px solid #0153bf;
}
/* 表格内每单元格样式 */
#dashboard .el-table td {
  padding: 0;
  background-color: #183847;
  border-bottom: 1px solid #0153bf;
}
/* 表格内每行 */
#dashboard .el-table__row {
  height: 30px;
  background-color: #183847;
}
/* 去除表格内最下面的一条线 */
#dashboard .el-table::before {
  height: 0px;
}
// 取消表格鼠标进入高亮显示
  .el-table__row:hover > td {
    background-color: transparent !important;
  }
</style>

第二种在弹窗中使用,弹窗中的表格,不知道为啥,使用上面的样式它不生效,但是下面的就有用

 .el-table th {
    background-color: transparent !important;
color: #000 !important;
    border-bottom: none;
    padding-bottom: 0;

  }
  .el-table tr {
    background-color: transparent !important;
    color: #000 !important;
    border: 1px solid #64707c !important;
  }
  .el-table__body {
    border-collapse: separate;
    border-spacing: 0px 10px;
  }
  .el-table td {
    padding: 6px 0;
    border: transparent; //表格下边框没有
  }
  .el-table .el-table__row {
    height: 27px;
  }
  .el-table td.is-center {
    border-top: 1px solid #0153bf !important;
    border-bottom: 1px solid #0153bf;
  }
  .el-table td.is-center:first-child {
    border-left: 1px solid #0153bf !important;
  }
  .el-table td.is-center:last-child {
    height: 27px;
    border-right: 1px solid #0153bf !important;
  }
  .el-table::before {
    height: 0px;
  }

4、去掉表格多选框

<style lang="scss" scoped>
//去掉表头多选框
::v-deep .el-table__header-wrapper .el-checkbox {
  display: none;
}
</style

5、表格自适应高度,但出现底部空白的现象

其实就是 el-table__body-wrapper的高度大于el-table__body
    handleClick(tab, event) {
      this.BpmGetList(this.form);//调用接口,刷新数据
      this.$nextTick(() => {
        this.$refs.tableHeight.doLayout(); //更新完数据之后,重新布局表格,为了防止底部出现空白(如果是在标签页中的表格自适应,那么在标签页中需要加v-if。让他在切换时重新渲染,因为标签页默认都渲染好了)
      });
      this.$forceUpdate();
    },

这篇文章看完如果您觉得有所收获,认为还行的话,就点个赞收藏一下呗

Guess you like

Origin blog.csdn.net/Qxn530/article/details/129301198