vue2+el-table 封装表格组件,基本够用了,带自动滚动

标题@[TOC](vue2+el-mentUI 封装的多功能表格组件,带自动滚动)

欢迎使用Markdown编辑器

表格组件页面

<!-- 自定义表单 -->
<template>
  <div class="tablx-box">
    <el-table
      v-loading="fetchLoading && data.length == 0"
      class="table"
      :data="data"
      ref="tableScroll"
      stripe
      border
      :max-height="maxHeight"
      :header-cell-style="{
        borderColor: '#003B7A',
        color: '#fff',
        height: '54px',
      }"
      :row-style="{
        color: '#fff',
      }"
      :cell-style="{
        padding: '5px',
        height: '52px',
        borderColor: '#00539F',
      }"
      row-class-name="tableRowClassName"
      :show-summary="showSummary"
      :summary-method="getSummaries"
      :element-loading-text="loadingText"
      @selection-change="handleSelectionChange"
      @mouseenter.native="autoScroll(true)"
      @mouseleave.native="autoScroll(false)"
    >
    // 添加选择表格功能
      <el-table-column
        v-if="selection"
        type="selection"
        align="center"
        width="55"
      />
      <el-table-column
        v-for="(item, index) in tableTitle"
        :key="item.key ? item.key : index"
        align="center"
        :prop="item.prop"
        :label="item.label"
        :sortable="item.sortable"
        :width="item.width ? item.width : null"
      >
        <template slot-scope="scope">
        //判断是否显示单元格按钮
          <template v-if="item.isBotton">
            <div style="display: flex; justify-content: space-between">
              <span style="padding-top: 7px"
                >{{ scope.row[scope.column.property] }}
              </span>
              <div class="inner-btn" @click="resetFn(scope.row)">重置</div>
            </div>
          </template>
          <template v-else>
            <span>{{ scope.row[scope.column.property] }} </span>
          </template>
        </template>
      </el-table-column>
      <slot name="actionColumn" />
    </el-table>
  </div>
</template>

<script>
export default {
  name: "CustomTable",
  props: {
  // 内容list
    data: {
      type: Array,
      default: () => [],
    },
    //懒加载
    fetchLoading: {
      type: Boolean,
      default: false,
    },
    loadingText: {
      type: String,
      default: "加载中...",
    },
    // 表头内容
    tableColumn: {
      type: Array,
      default: () => [],
    },
    selection: {
      type: Boolean,
      default: false,
    },
   // 是否在表尾显示合计行
    showSummary: {
      type: Boolean,
      default: false,
    },
    // 自定义的合计计算方法
    getSummaries: {
      type: Function,
    },
    maxHeight: {
      type: String,
      default: "410px",
    },
  },
  data() {
    return {
      scrolltimer: null, // 滚动时间参数
      animate: false, //默认false
    };
  },
  computed: {
    tableTitle() {
      if (!this.data || this.data.length === 0) return [];
      const titles =
        this.tableColumn && this.tableColumn.length > 0
          ? this.tableColumn
          : (this.data &&
              this.data.length > 0 &&
              Object.keys(this.data[0]).map((item) => {
                return {
                  prop: item,
                  label: item,
                };
              })) ||
            [];
      return titles;
    },
  },
  mounted() {
    this.autoScroll(); //滚动函数
  },
  beforeDestroy() {
    this.autoScroll(true);
  },
  methods: {
    handleSelectionChange(val) {
      if (this.selection) {
        this.$emit("selectionChange", val);
      }
    },
    toggleSelection(rows) {
      if (rows) {
        rows.forEach((row) => {
          this.$refs.table.toggleRowSelection(row);
        });
      } else {
        this.$refs.table.clearSelection();
      }
    },
    // 斑马线颜色控制
    tableRowClassName({ row, rowIndex }) {
      if (rowIndex % 2 !== 0) {
        return "el-table__row--striped";
      }
    },
      // 单元格内函数-父子通信
    resetFn(row) {
      this.$emit("resetFn", row);
    },

    // 自动轮播效果
    autoScroll(stop) {
      const table = this.$refs.tableScroll;
      // 拿到表格中承载数据的div元素
      const divData = table.$refs.bodyWrapper;
      // 拿到元素后,对元素进行定时增加距离顶部距离,实现滚动效果(此配置为每100毫秒移动1像素)
      if (stop) {
        //再通过事件监听,监听到 组件销毁 后,再执行关闭计时器。
        window.clearInterval(this.scrolltimer);
      } else {
        this.scrolltimer = window.setInterval(() => {
          // 元素自增距离顶部1像素
          divData.scrollTop += 1;
          // 判断元素是否滚动到底部(可视高度+距离顶部=整个高度)
          if (
            divData.clientHeight + divData.scrollTop >=
            divData.scrollHeight
          ) {
            // 重置table距离顶部距离
            // this.data.unshift(...this.data);
            divData.scrollTop = 0;
          }
        }, 30); // 滚动速度
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.test-div {
  animation: fadeOut 500ms linear;
}

.inner-btn {
  width: 80px;
  height: 36px;
  cursor: pointer;
  text-align: center;
  line-height: 36px;
  color: #00d8f4;
  border-radius: 4px 4px 4px 4px;
  border: 1px solid #00d8f4;
  &:hover {
    background-color: #888585;
    color: #fff;
  }
}
::v-deep .el-table__header-wrapper {
  .has-gutter {
    color: #1d2129;
    th {
      background: #003b7a;
    }
    tr {
      background: #003b7a;
    }
  }
}

::v-deep .el-table__body {
  width: 100% !important;
}
::v-deep .el-table__footer {
  width: 100% !important;
}
::v-deep .el-table__header {
  width: 100% !important;
}

::v-deep .el-table__empty-block {
  width: 100% !important;
}

::v-deep .cell.el-tooltip {
  width: 100% !important;
}

::v-deep .el-table__body tr,
::v-deep .el-table__body td {
  padding: 0;
  height: 34px;
}
// 显示的颜色
::v-deep .el-table__body tr.el-table__row--striped td {
  background-color: #043272 !important;
}
::v-deep .el-table__row {
  background: #031a3c !important;
}

::v-deep .el-table__body tr:hover > td {
  background-color: #3d5e8d !important;
}

::v-deep .el-table--border,
.el-table--group {
  border: 1px solid #003b7a;
}

// 隐藏滚动条
::v-deep .el-table__body-wrapper {
  &::-webkit-scrollbar {
    // 整个滚动条
    width: 0 !important; // 纵向滚动条的宽度
    background: transparent;
    border: none;
  }

  &::-webkit-scrollbar-track {
    // 滚动条轨道
    border: none !important;
  }
  /* 滚动条轨道内部空白区域样式 */
  &::-webkit-scrollbar-track {
    background-color: transparent; /* 设置轨道背景色为浅灰色 */
  }
}
</style>

父组件中使用

<template>
  <ContentTitle title="">
    <div class="agent-container padding-top-20">
        <div class="left-box">
          <custom-table
            :fetch-loading="listLoading"
            :data="list"
            maxHeight="828px"
            :loading-text="loadingText"
            :table-column="tableColumn"
            :selection="false"
          >
          // 在表格末尾行添加操作按钮
           <template v-slot:actionColumn>
              <el-table-column label="操作" align="center" width="200">
                <template slot-scope="{ row }">
                  <span class="pointer mlr10" @click="handleEdit(row)"
                    >修改</span
                  >
                  <span class="pointer red mlr10" @click="handleDel(row)"
                    >删除</span
                  >
                </template>
              </el-table-column>
            </template>
          </custom-table>
        </div>
    </div>
  </ContentTitle>
</template>

<script>
import CustomTable from "@/components/CustomTable";

import * as API from "@/axios/common.js";
export default {
  components: {
    CustomTable,
  },
  data() {
    return {
      loadingText: "加载中...",
      list: [],
      listLoading: false,
      // 自定义Pagination的参数
      hideOnSinglePage: false,
      listQuery: {
        pageNum: 1, // pageNum
        pageSize: 20, // pageSize
      },
      // 根据接口和设计稿设置表头
      tableColumn: [
        {
          prop: "startTime",
          label: "开始时间",
           width: "530px", // 单元格宽度,自己看需求设置
        },
           {
          prop: "realName",
          label: "客户名称",
          width: "339px",
          isBotton: true, // 单元格内是否加按钮
        },
        {
          prop: "durationTime",
          label: "持续时间",
              // 自定义方法,复杂表格数据使用
       //   formatter: (row) => {
       //  return row.endTime == null ? "--" : row.endTime;
       //   },
        },
        {
          prop: "deviceWarningName",
          label: "报警代码",
        },
        {
          prop: "remark",
          label: "详情说明",
        },
      ],
    };
  },
  created() {
    this.getList();
  },
  methods: {
    getList() {
      this.listLoading = true;
      // 自己封装的axios请求
      API.****({
        ...this.listQuery,
      }).then((res) => {
        this.list = res.data.list || [];
        this.listLoading = false;
      });
    },
  },
};
</script>

</style>

效果图

在这里插入图片描述

你可能感兴趣的:(javascript,vue.js,前端)