vue2 封装表格组件

包含:多选框、多级表头、点击事件、树形表格、合计数、单击行多选框显示被勾选。

<template>
  <!-- 简单表格、多层表头、页码、没有合并列行、显示合计、单击某一行,该行多选框显示已选中 -->
  <div class="maintenPublictable">
    <!--cell-style 改变某一列行的背景色 -->
    <!-- tree-props 配置树形子表
    row-click: 某一行单击事件
    highlight-current-row:高亮选中某行
    default-expand-all:默认是否展开字列表
    current-change:管理选中时触发的事件
    selection-change:多选框
    row-key="id":    id:一定要跟后台返回来的id一致,不一致,会出错
    show-summary: 显示合计
    summary-method: 合计指定的某一列
    row-dblclick: 某一行被双击
    stripe :斑马纹
    border
    show-overflow-tooltip :当内容过长被隐藏时显示 tooltip
    -->
    <!-- :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" -->
    <el-table
      class="rollTableRow"
      ref="table"
      stripe
      :data="tableData"
      :height="getHeight"
      :show-summary="showSum"
      :summary-method="getSummaries"
      @selection-change="handleSelectionChange"
      :key="itemKey"
      :cell-style="tableCellStyle"
      @row-click="clickRow"
      @row-dblclick="rowDblclick"
      row-key="ID"
      :default-expand-all="defaultall"
      :highlight-current-row="highlightCurrent"
      @current-change="handleCurrentChangeRow"
      :tree-props="{ children: 'Children' }"
      header-row-class-name="headerStyle"
      v-loading="loading"
      element-loading-text="拼命加载中"
      :element-loading-svg="svg"
      element-loading-background="#062b54"
    >

      <el-table-column
        type="index"
        width="55"
        label="序号"
      >
      </el-table-column>
      <el-table-column
        type="selection"
        v-if="isSelection"
        width="55"
      >
      </el-table-column>
      <!-- item.direction 方向,判断居中还是靠右 -->
      <template v-for="(item, index) in tableHeader">
        <!-- 1. 这是第一层 -->
        <!-- sortable: 排序     item.direction -->
        <el-table-column
          v-if="!item.child"
          :key="index"
          :prop="item.prop"
          :label="item.label"
          header-align="center"
          align="center"
          :min-width="item.width"
          :sortable="item.sortable"
          show-overflow-tooltip
        >
        </el-table-column>
        <!-- 二级表头 -->
        <el-table-column
          v-else
          :key="index + 1"
          :prop="item.prop"
          :label="item.label"
          :type="item.type"
          :align="item.align || 'center'"
        >
          <template v-for="(childItem, index) in item.child">
            <!-- 三级表头 -->
            <el-table-column
              v-if="!childItem.child"
              :key="index"
              :prop="childItem.prop"
              :label="childItem.label"
              header-align="center"
              :align="childItem.center"
              :min-width="childItem.width"
            >
            </el-table-column>
            <el-table-column
              v-else
              :key="index + 1"
              :prop="childItem.prop"
              :label="childItem.label"
              :type="childItem.type"
              :align="childItem.align || 'center'"
            >
              <template v-for="(childItem, index) in item.child">
                <!-- 这是第三层 -->
                <el-table-column
                  v-if="!childItem.child"
                  :key="index"
                  :prop="childItem.prop"
                  :label="childItem.label"
                  header-align="center"
                  :align="childItem.center"
                  :min-width="childItem.width"
                >
                </el-table-column>
                <el-table-column
                  v-else
                  :key="index + 1"
                  :prop="childItem.prop"
                  :label="childItem.label"
                  :type="childItem.type"
                  :align="childItem.align || 'center'"
                >
                </el-table-column>
              </template>
            </el-table-column>
          </template>
        </el-table-column>
      </template>
      <!-- 表格最后一列是否是勾选框【完成情况】 -->
      <el-table-column
        v-if="isSelect"
        align="center"
      >
        <template
          slot="header"
          slot-scope="scope"
        >
          <el-checkbox
            @change="allCheck(isAllcheck, tableData, ClickIdsList, isIndeterminate)"
            size="large"
            v-model="isAllcheck"
            :indeterminate="isIndeterminate"
          ></el-checkbox>完成情况
        </template>
        <template slot-scope="scope">
          <!-- <el-button @click="Ones(scope)">122333</el-button> -->
          <el-checkbox
            @change="OnesClick(scope.row)"
            v-model="scope.row.check"
            class="ml-4"
            size="large"
          ></el-checkbox>
        </template>
      </el-table-column>
    </el-table>
    <!--  分页 -->
    <div
      v-if="showFenYe"
      class="fenYeStyle"
    >
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="page.currentPage"
        :page-sizes="[5, 10, 15, 20]"
        :page-size="page.pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="page.total"
      >
      </el-pagination>
    </div>
  </div>
</template>
<script>
// import preventBack from "vue-prevent-browser-back"; //阻止返回
import { PublicFunction } from "@/utils/vuePublic";

export default {
  name: "maintenPublictable",
  components: {},
  props: {
    // 接收的是:是否有分页、是否有勾选
    columns: {
      type: Object,
      default: {},
    },
    // 接收的是:页码
    pagination: {
      type: Object,
      default: {},
    },
  },
  data() {
    return {
      tableHeader: [], //表头
      tableData: [], //数据
      itemKey: "",

      types: 1, //用于合并,判断是否需要合并
      //#region 与父组件关联
      getHeight: 20, //高度
      isSelect: false, //勾选框
      showFenYe: false, //是否有分页
      isSelection: false, //是否有多选框
      isTag: false, //是否有标签
      defaultall: false, //是否默认展开所有行(用于有树状结构的表格)
      highlightCurrent: false, //高亮选中
      showSum: false, //合计
      //#endregion

      // 页码
      page: {
        currentPage: 1, //当前页
        pagesize: 10, //当前页的条数
        total: 20, //总数
      },

      //多选框
      multipleSelection: [],

      //#region 用于右侧的完成情况
      //选择
      isAllcheck: false, //全选
      ClickIdsList: [], //已选择集合组
      isIndeterminate: false, //部分选中,默认是false
      //#endregion
      loading: true,
    };
  },
  // mixins: [preventBack], //注入  阻止返回上一页

  created() {},
  watch: {
    // 监听对象的写法(监听页码的变化)
    pagination: {
      handler(newValue, oldVal) {
        this.page.total = newValue.total;
      },
      deep: true, // 深度监听
      // immediate: true, //写上它,初始化时也会调用监听
    },
  },
  mounted() {
    this.init();
  },
  methods: {
    // Ones(value) {
    //   console.log("12121212", value);
    // },
    //在父组件初始化时,需要获得页码,所以子组件初始化时把页码传过去
    init() {
      let _this = this;
      _this.getHeight = this.columns.getHeight;
      _this.showSum = this.columns.showSum; //合计
      _this.defaultall = this.columns.defaultall; //是否展开所有行
      _this.isSelect = this.columns.isSelect; //右侧的完成情况
      _this.isTag = this.columns.isTag; //是否有标签
      _this.showFenYe = this.columns.showFenYe;
      _this.isSelection = this.columns.isSelection; //左侧的多选框
      _this.highlightCurrent = this.columns.highlightCurrent; //高亮选中
      _this.page.total = this.pagination.total;
      _this.$emit("getPage", {
        data: {
          pageSize: _this.page.pagesize,
          pageNum: _this.page.currentPage,
          isTypes: 1,
        },
      });
    },
    //一页有多少条数据
    handleSizeChange(val) {
      let _this = this;
      _this.page.pagesize = val;
      // 子传父
      _this.$emit("getPage", {
        data: {
          pageSize: _this.page.pagesize,
          pageNum: _this.page.currentPage,
          isTypes: 2,
        },
      });
    },
    //第几页/切换页码
    handleCurrentChange(val) {
      let _this = this;
      _this.page.currentPage = val;
      _this.$emit("getPage", {
        data: {
          pageSize: _this.page.pagesize,
          pageNum: _this.page.currentPage,
          isTypes: 2,
        },
      });
    },
    //表头
    SetDataTableHeader(GetDataLists) {
      //重新渲染,itemKey用于处理Table不渲染的问题
      this.itemKey = Math.random();
      //重新渲染数据表
      this.tableHeader = GetDataLists;
      // this.$forceUpdate()
    },
    //table值
    SettableData(tabledata) {
      let _this = this;
      _this.itemKey = Math.random();
      _this.tableData = tabledata;
    },

    //左侧:多选框
    handleSelectionChange(val) {
      this.multipleSelection = val;
      this.$emit("handleSelectionChange", val);
    },

    //#region 下面这个是用于最右侧的完成情况
    //全选 调取公共js文件的方法
    allCheck(isAll, tableData, checkList, isCheck) {
      //接收传过来的值
      let objData = PublicFunction.allCheck(
        isAll,
        tableData,
        checkList,
        isCheck
      );
      this.isAllcheck = objData.isAll;
      this.ClickIdsList = objData.checkList;
    },

    //单行选择
    OnesClick(rows) {
      if (rows.check) {
        this.ClickIdsList.push(rows.id);
      } else {
        let index = this.ClickIdsList.indexOf(rows.id);
        this.ClickIdsList.splice(index, 1);
      }
      this.isIndeterminate =
        this.ClickIdsList.length > 0 &&
        this.ClickIdsList.length < this.tableData.length;
      this.isAllcheck = this.ClickIdsList.length == this.tableData.length;
    },
    //#endregion

    // 合并单元格
    objectSpanMethod({ row, column, rowIndex, columnIndex }, tableData, types) {
      if (types === 1) {
        switch (
          columnIndex // 将列索引作为判断值
        ) {
          // 通过传递不同的列索引和需要合并的属性名,可以实现不同列的合并(索引0,1 指的是页面上的0,1)
          case 2:
            return PublicFunction.MergeCol(tableData, "itemDetail", rowIndex);
          case 1:
            return PublicFunction.MergeCol(tableData, "item", rowIndex);
        }
      } else {
        //保障作业
        switch (columnIndex) {
          case 1:
            return PublicFunction.MergeCol(tableData, "item", rowIndex);
        }
      }
      //判断检查内容是否为空
      // if (
      //   tableData[columnIndex].checkContent != undefined ||
      //   tableData[columnIndex].checkContent != null
      // ) {
      // } else {
      // }
    },

    // 提交(在父组件点击提交时调用这个方法)
    childSumbit() {
      let param = {
        tabledata: this.tableData,
        ClickIdsList: this.ClickIdsList,
        multipleSelection: this.multipleSelection,
      };
      // 把值传给父组件
      this.$emit("sumbitData", param);
    },

    //行点击事件
    clickRow(row, column, event) {
      this.$emit("rowClick", row);
    },

    //某一行被双击
    rowDblclick(row, column, event) {
      this.$emit("rowDoubleClick", row);
    },

    // 行选中时间
    handleCurrentChangeRow(val) {
      this.$emit("handleCurrentChangeRow", val);
    },

    // 改变某一列的行的背景色
    tableCellStyle({ row, column, rowIndex, columnIndex }) {
      //如果是第一列
      // if (columnIndex === 1) {
      //   //如果这一行的字段==未维护
      //   if (row.state == "未维护") {
      //     // 如果是未维护——背景色浅蓝色,字体色蓝色;
      //     return "background:#ecf5ff; color:#409eff";
      //   } else if (row.state == "已维护") {
      //     // 如果是已维护——背景色绿色,字体色白色;
      //     return "background:#67c23aa6;color:#fff ";
      //   } else if (row.state == "部分维护") {
      //     // 如果是已维护——背景色棕色,字体色白色;
      //     return "background:#e6a23cab;color:#fff ";
      //   } else {
      //   }
      // } else {
      if (row.EliminateTime < 24 && columnIndex === 7) {
        return { color: "red" };
      }
    },

    // 测试,取消荀泽
    setCurrent() {
      this.$refs.table.setCurrentRow();
    },
    // 合计 指定某一列添加合计

    getSummaries(param) {
      const { columns, data } = param;
      const sums = [];
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = "合计";
          return;
        } else if (column.property == "Amount") {
          //如果是经费(正常的加减法)
          const values = data.map((item) => Number(item[column.property]));
          if (!values.every((value) => isNaN(value))) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr);
              var sum = 0;
              if (!isNaN(value)) {
                sum = Number(Number(prev) + Number(curr)).toFixed(2);
                return sum;
              } else {
                return prev;
              }
            }, 0);
            sums[index] += " ";
          }
        }
      });
      return sums;
    },

    /**
     * 单击某一行,该行多选框显示已选中
     */
    toggleSelection(rows) {
      if (rows) {
        // rows.forEach((row) => {
        //   this.$refs.table.toggleRowSelection(row);
        // });
        this.$refs.table.toggleRowSelection(rows);
      } else {
        this.$refs.table.clearSelection();
      }
    },
  },
  //#endregion
};
</script>

<style scoped>
/* 表格表头 */
.maintenPublictable ::v-deep .el-table th,
::v-deep .el-table thead.is-group th.el-table__cell {
  /* background: linear-gradient(147deg, #70c0ff, #2f9fff); */
  /* background: transparent; */
  background: #295d85;
  color: #fff;
  padding: 0;
  margin: 0;
  height: 3rem !important;
}

/*****滚动条影藏 */

::v-deep .el-table--scrollable-y ::-webkit-scrollbar {
  display: none !important;
}

/**lable名字 */
::v-deep .el-checkbox__label {
  color: #fff;
}

.fenYeStyle {
  position: absolute;
  /* bottom: 2rem; 第二次改动 */
  /* bottom: 0rem; */
  /* left: 33%; 居左*/
}

/* 背景透明 */
::v-deep .el-table tr {
  background-color: transparent;
  color: #fff;
}

/* 表格背景透明 */
.rollTableRow {
  background: transparent;
  /* border边框 */
  --el-table-border-color: transparent;
}

/* 表格背景图 */
.maintenPublictable {
  background: url("@/assets/imgList/tableBG.png") no-repeat;
  background-size: 100% 100%;
  padding: 4%;
}

/* 鼠标悬浮时 表格背景色及字体颜色 */
::v-deep .el-table tbody tr:hover > td {
  background-color: rgb(65, 111, 180) !important;
  color: #ffffff;
}

/* 斑马线颜色 */
::v-deep
  .el-table--striped
  .el-table__body
  tr.el-table__row--striped
  td.el-table__cell {
  background: #295d85;
}

/* 箭头 */
::v-deep .el-table__expand-icon > .el-icon {
  color: #f3f3f3;
}
</style>


<style scoped>
/* 页码 */
::v-deep .el-pagination__total,
::v-deep .el-pagination__jump {
  color: #f3f3f3;
}

::v-deep .el-select .el-input__wrapper {
  cursor: pointer;
  background-color: #418de7;
  border: none;
  box-shadow: none;
}

::v-deep .el-select .el-input__inner {
  cursor: pointer;
  color: #f3f3f3;
}

::v-deep .el-pager li.is-active {
  color: #f3f3f3;
  cursor: default;
  font-weight: 700;
  background-color: #418de7;
}

/* 箭头按钮 */
::v-deep .el-input__wrapper,
::v-deep .el-pagination button:disabled,
::v-deep .el-pagination button,
::v-deep .btn-next {
  background-color: #418de7;
  box-shadow: none;
  color: #f3f3f3;
}

::v-deep .el-pagination .el-input__inner {
  color: #f3f3f3;
}

::v-deep .el-pager li.is-active,
::v-deep .el-pager li {
  background-color: #418de7;
  color: #f3f3f3;
}
</style>

猜你喜欢

转载自blog.csdn.net/CMDN123456/article/details/131827340