自己封装table表格可以的动态添加行和列

92 阅读2分钟

效果图,通过点击“+”号来实现表格动态添加,动态添加行列序号

image.png 图片是从iconfont下载:www.iconfont.cn/search/inde… 代码如下(随便写的代码重复较多可自行优化)

<template>
  <div>
    <div class="search_for">
      <div class="seach_but">
        <el-button type="primary" @click="gatherSynchronous()"
          >采集点同步</el-button
        >
        <!-- <el-button @click="addTable('hang')">加一行</el-button>
        <el-button @click="addTable('lie')">加一列</el-button> -->
      </div>
    </div>

    <div class="content" ref="contentRef">
      <div
        class="iamgeIcon"
        :style="{ left: `${setWidth}px` }"
        @click="addTable('lie')"
      >
        <div class="iconJia">+</div>
        <el-image
          style="width: 100%; height: 100%"
          src="/img/shuiDi.png"
        ></el-image>
      </div>
      <div
        class="iamgeLieIcon"
        :style="{ top: `${setHeight}px` }"
        @click="addTable('hang')"
      >
        <div class="iconJia">+</div>
        <el-image
          style="width: 100%; height: 100%"
          src="/img/lieDi.png"
        ></el-image>
      </div>
      <div class="table" :style="{ width: `calc(100vw - ${widthEl})` }">
        <el-checkbox-group v-model="checkList" @change="checkBoxChange">
          <table ref="myTable">
            <thead>
              <tr>
                <td rowspan="2" colspan="2">采集点行/列</td>
                <td
                  v-for="(item, index) in tableData[0]"
                  :key="'header-' + index"
                >
                  {{ index + 1 }}
                </td>
              </tr>
              <tr>
                <td
                  v-for="(item, index) in tableData[0]"
                  :key="'header-' + (index + tableData[0].length)"
                >
                  {{ `00000${index + 1} ` }}
                </td>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="(row, rowIndex) in tableData"
                :key="'data-row-' + rowIndex"
              >
                <td class="tableTd">
                  <div style="width: 40px">{{ +rowIndex + 1 }}</div>
                </td>
                <td class="tableTd">
                  <div style="width: 60px">{{ "00000" + (+rowIndex + 1) }}</div>
                </td>
                <td v-for="(item, index) in row" :key="'data-item-' + index">
                  <el-checkbox :label="`${item.x}-${item.y}`" v-if="checkboxEl">
                    <p
                      style="
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        width: 35px;
                        height: 35px;
                        background: #409eff;
                        border-radius: 50%;
                        color: #fff;
                      "
                    >
                      {{ item.x }} - {{ item.y }}
                    </p>
                  </el-checkbox>
                  <p
                    v-else
                    style="
                      display: flex;
                      justify-content: center;
                      align-items: center;
                      width: 35px;
                      height: 35px;
                      background: #409eff;
                      border-radius: 50%;
                      color: #fff;
                    "
                  >
                    {{ item.x }} - {{ item.y }}
                  </p>
                </td>
              </tr>
            </tbody>
   
          </table>
        </el-checkbox-group>
      </div>
    </div>

    <div style="display: flex; justify-content: center" v-if="checkboxEl">
      <el-button @click="cancel">取 消</el-button>
      <el-button type="primary" @click="submitGatherInfoForm()"
        >确 定</el-button
      >
    </div>
  </div>
</template>

<script>
  export default {
    name: "",
    props: {
      plantRow: Object,
      widthEl: {
        type: String,
        default: "16vw",
      },
      checkboxEl: {
        type: Boolean,
        default: false,
      },
      gatherInfoVisible: {
        type: Boolean,
        default: false,
      },
    },
    data() {
      return {
        plantId: "",
        tableData: [
          [
            { x: 1, y: 1 },
            { x: 1, y: 2 },
            { x: 1, y: 3 },
            { x: 1, y: 4 },
            { x: 1, y: 5 },
          ],
        ],
        checkList: [],
        setWidth: "0",
        setHeight: "0",
      };
    },
    computed: {},
    watch: {},
    created() {},
    mounted() {
      this.checkList = [];
      this.$nextTick(() => {
        this.liePosition();
        this.hangPosition();
      });
    },
    methods: {
      liePosition() {
        this.setWidth =
          +this.$refs.myTable.offsetWidth - 8 < +this.$refs.contentRef.offsetWidth
            ? +this.$refs.myTable.offsetWidth - 8
            : +this.$refs.contentRef.offsetWidth - 15;
      },
      hangPosition() {
        this.setHeight =
          +this.$refs.myTable.offsetHeight - 18 <
          +this.$refs.contentRef.offsetHeight
            ? +this.$refs.myTable.offsetHeight - 18
            : +this.$refs.contentRef.offsetHeight - 18;
      },
      checkBoxChange(value) {
        console.log(value);
      },
      addTable(type) {
        if (type == "lie") {
          this.tableData.forEach((item, index) => {
            item.push({ x: item[0].x, y: item.length + 1 });
          });
          this.$nextTick(() => {
            this.liePosition();
          });
        } else {
          let arr = [];
          this.tableData[this.tableData.length - 1].forEach((item) => {
            arr.push({ x: this.tableData.length + 1, y: item.y });
          });
          this.$set(this.tableData, this.tableData.length, arr);
          this.$nextTick(() => {
            this.hangPosition();
          });
        }
      },
      // 采集点同步
      gatherSynchronous() {},
      // 取消
      cancel() {
        this.$emit("update:gatherInfoVisible", false);
      },
      submitGatherInfoForm() {
        this.$emit("checkboxList", this.checkList);
        this.cancel();
      },
    },
  };
</script>

<style lang="less" scoped>
  .content {
    display: flex;
    flex-direction: column;
    position: relative;
    .iamgeIcon {
      width: 35px;
      height: 35px;
      position: absolute;
      top: -28px;
      z-index: 99999;
      cursor: pointer;
      .iconJia {
        position: absolute;
        z-index: 99999;
        color: #fff;
        top: 1px;
        left: 12px;
        font-size: 20px;
      }
    }
    .iamgeLieIcon {
      width: 35px;
      height: 35px;
      position: absolute;
      left: -17px;
      z-index: 99999;
      cursor: pointer;
      .iconJia {
        position: absolute;
        z-index: 99999;
        color: #fff;
        top: 6px;
        left: 7px;
        font-size: 20px;
      }
    }
    .table {
      margin: 0px 10px;
      height: 465px;
      overflow: auto;
      text-align: center;
      background-color: white;
      position: relative;
    }

    .table table {
      border-right: 1px solid #acacac;
      border-bottom: 1px solid #acacac;
      border-spacing: 0;
      width: 40px;
      border-collapse: collapse;
      position: relative;
    }

    .table table td {
      border-left: 1px solid #acacac;
      border-top: 1px solid #acacac;
      text-align: center;
      font-size: 12px;
      font-weight: bold;
      border-right: 1px solid #acacac;
    }

    .table table tr td {
      height: 40px;
      padding: 0 15px;
      border-top: 1px solid #acacac;
    }

    .table table thead tr:first-child {
      background-color: #1f89ee;
    }
    .table table thead {
      position: sticky;
    }

    .table table thead tr:nth-child(2) {
      background-color: #1f89ee;
    }
    .tableTd {
      background-color: #1f89ee;
    }
  }
</style>