前段时间公司做了一个新项目,后台管理这种,大部分都是表格,UI框架用的是element,所以我刚好把表格组件封装了一下,

elementUI表格组件常用的功能就是单选/多选框勾选,数据展示,行内按钮操作等,这块我也是基于本当前项目的需求大概封装的,比elementUI多的就是一个动态显示隐藏列的功能,这里记录一下

<template>
  <div class="tabletemplate">
    <!-- 动态显示隐藏列功能 -->
    <el-dropdown
      v-if="selectColumns" // 动态列功能是否显示
      :hide-on-click="false"
      @visible-change="dropdownSelectShow"
      class="el-dropdown-selectColumn"
      trigger="click"
    >
      <span class="dropdown-button" :style="theme.sysTheme.styleLevel4">
        <i
          class="icon iconfont iconcaidan1"
          :style="theme.sysTheme.colorLevel3"
        ></i>
      </span>
      <el-dropdown-menu slot="dropdown" style="text-align: center;">
        <!-- <CheckboxGroup v-model="tableColumnsCheckedShow" @on-change="changeTableColumns"> -->
        <div class="dropdowntable" style="text-align: left;">
          <el-dropdown-item v-for="(item, index) in tableColumns" :key="index">
            <!-- <Checkbox :label="item.title">{{item.title}}</Checkbox> -->
            <template>
              <el-checkbox
                :checked="item.isShow"
                v-model="item.isShow"
                @change="checkChange(item)"
                >{{ item.title }}</el-checkbox
              >
            </template>
          </el-dropdown-item>
        </div>
        <!-- <el-button
          type="primary"
          style="margin: auto;padding: 5px 15px;"
          @click="buttonclick(tableColumns)"
        >确定</el-button> -->
        <!-- </CheckboxGroup> -->
      </el-dropdown-menu>
    </el-dropdown>

    <el-table
      :data="tableData"
      stripe
      border
      v-loading="loading"
      highlight-current-row
      :header-cell-style="{
        'background-color': headerBackColor,
        color: '#333'
      }"
      :cell-style="{
        'background-color': '#ffffff',
        'border-color': cellBorderColor
      }"
      :row-style="{ border: 'none' }"
      show-overflow-tooltip
      style="width: 100%;margin-top: 0.24rem;"
      @selection-change="handleSelectionChange"
      ref="multipleTable"
    >
      <!--选择-->
      <el-table-column
        v-if="selectionShow" // 表格是够显示多选框
        type="selection"
        align="center"
        :width="selectionWith"
      ></el-table-column>
      // 单选框,多选单选只能选则显示一个或者都不显示
      <el-table-column v-if="radioShow && !selectionShow" :width="radioWidth">
        <template slot-scope="scope">
          <el-radio
            v-model="radioVal"
            @change.native="getRow(scope.row)"
          ></el-radio>
        </template>
      </el-table-column>
      <!--序号 自定义列序号-->
      <el-table-column
        v-if="indexShow"
        type="index"
        align="center"
        label="序号"
        fixed="left"
        :width="indexWidth"
      >
        <template slot-scope="scope">
          <span>{{ (page - 1) * size + scope.$index + 1 }}</span>
        </template>
      </el-table-column>
      <!-- :width="column.width ? column.width: ''" -->
      <!-- 表格数据列 -->
      <el-table-column
        align="center"
        v-for="column in tableColumns"
        v-if="selectColumns ? column.isShow || !isshowShow : true"
        :key="column.key"
        :label="column.title"
        show-overflow-tooltip
      >
        <template slot-scope="scope">
          <span
            v-if="scope.row.activeStatus === '在线'"
            style="color:#13CE66"
            >{{ scope.row.activeStatus }}</span
          >
          <!-- <span v-else-if="scope.row.accessCode">
            <span v-if="scope.row.accessCode === '3'"
              >高于{{ scope.row.additionalRule }}分钟不得分</span
            >
            <span v-else-if="scope.row.accessCode === '4'">无</span>
            <span v-else>低于{{ scope.row.additionalRule }}%不得分</span>
          </span> -->
          <span v-else>{{ scope.row[column.key] }}</span>
        </template>
      </el-table-column>
      <!--操作-->
      <el-table-column
        v-if="tableOperationShow" // 操作按钮是否显示
        :width="operationColumnWidth"
        label="操作"
        align="center"
        fixed="right"
      >
        <!-- 操作列按钮的个数,名称,功能都是可以自定义的 -->
        <template slot-scope="scope">
          <!-- <div class="tablecloumnview"> -->
          <span
            class="font-small font-color-light operationSpan"
            v-if="viewDetail"
            @click="tableOperationBtn1Handle(scope.row)"
            >{{ tableOperationText1 }}</span
          >
          <span
            class="font-small font-color-light operationSpan"
            v-if="linkLogin"
            @click="tableOperationBtn2Handle(scope.row)"
            >{{ tableOperationText2 }}</span
          >
          <span
            class="font-small font-color-light operationSpan"
            v-if="linkLogout"
            @click="tableOperationBtn3Handle(scope.row)"
            >{{ tableOperationText3 }}</span
          >
          <!-- </div> -->
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

该组件可以动态设置是否显示动态列功能,那么什么是动态列功能呢,其实就是一个按钮,点击会出现一个下拉框,里面是表格所有列名组成的列表,每一个列名可以根据需求显示,勾选则显示,取消勾选则隐藏。实现原理是v-if控制当前列的显示,表格列数据中有一个参数用来控制当前列的显示与隐藏。

<script>
import { mapGetters } from "vuex";
import createUpDeleteGive from "@/components/buttons/createUpDelGive"; // 按钮组件,很简单不做介绍
export default {
  name: "tabletemplate",
  components: {
    createUpDeleteGive
  },
  props: {
    headerBackColor: { // 表头背景颜色
      type: String,
      default: "#F5F5F5"
    },
    cellBackColor: { // 表格单元格背景颜色
      type: String,
      default: "#FFFFFF"
    },
    cellBorderColor: { // 表格单元格边框颜色
      type: String,
      default: "#E6E6E6"
    },
    selectColumns: { // 是否显示动态列功能,默认显示
      // 动态列功能
      type: Boolean,
      default: true
    },
    tableData: { // 表格数据
      type: Array,
      required: true,
      default: function() {
        return [];
      }
    },
    tableColumns: { // 表格列数据
      type: Array,
      required: true,
      default: function() {
        return [];
      }
    },
    isshowShow: {
      // 是否控制列的动态显示 默认控制
      type: Boolean,
      default: true
    },
    page: {
      type: Number,
      default: 1
    },
    size: {
      type: Number,
      default: 10
    },
    selectionWith: {
      type: Number,
      required: false,
      default: 50
    },
    radioWidth: {
      type: Number,
      required: false,
      default: 40
    },
    operationColumnWidth: {
      // 表格操作列宽度
      type: Number,
      required: false,
      default: 100
    },
    indexWidth: {
      type: Number,
      required: false,
      default: 55
    },
    selectionShow: {
      // 多选   默认显示多选
      type: Boolean,
      default: true
    },
    radioShow: {
      // 单选 使用单选应将多选置为false
      type: Boolean,
      default: false
    },
    indexShow: {
      // 序号列
      type: Boolean,
      default: true
    },
    tableOperationShow: {
      // 最后操作列
      type: Boolean,
      required: false,
      default: false
    },
    linkLogin: {
      type: Boolean,
      required: false,
      default: false
    },
    linkLogout: {
      type: Boolean,
      required: false,
      default: false
    },
    viewDetail: {
      type: Boolean,
      default: true
    },
    loading: {
      type: Boolean,
      default: false
    },
    tableOperationText1: {
      type: String,
      default: "查看详情"
    },
    tableOperationText2: {
      type: String,
      default: "链路登录"
    },
    tableOperationText3: {
      type: String,
      default: "链路注销"
    }
  },
  data() {
    return {
      tableColumnsCheckedShow: [],
      radioVal: -1
    };
  },
  methods: {
    handleSelectionChange(val) {
      // console.log(val);
      this.$emit("handleSelectionChange", val);
    },
    tableOperationBtn1Handle(row) {
      this.$emit("tableOperationBtn1Handle", row);
    },
    tableOperationBtn2Handle(row) {
      this.$emit("tableOperationBtn2Handle", row);
    },
    tableOperationBtn3Handle(row) {
      this.$emit("tableOperationBtn3Handle", row);
    },
    checkChange(val) {
      console.log("checkChange");
      // console.log(val);
    },
    getRow(row) {
      // console.log(row);
      this.$emit("giveTableRowData", row);
    },
    buttonclick(row) {},
    reset() {
      this.radioVal = -1;
      this.$refs["multipleTable"].clearSelection();
    },
    dropdownSelectShow(val) {
      if (val === true) {
        // var mo = function(e) {
        //   e.preventDefault();
        // };
        // document.body.style.overflow = "hidden";
        // document.addEventListener("touchmove", mo, false); //禁止页面滑动
        var scorllbar = document.querySelector(".form-table-content");
        scorllbar.addEventListener(
          "scorll",
          function(e) {
            e.preventDefault();
            e.stopPropagation();
            console.log("页面滚动事件");
            scorllbar.scrollTop = 0;
          },
          { passive: false }
        );
      }
    }
  },
  mounted() {},
  computed: {
    ...mapGetters(["currentNav", "theme"])
  }
};
</script>
<style lang="scss" scoped>
.tabletemplate {
  .el-dropdown-selectColumn {
    position: relative;
    float: right;
    .dropdown-button {
      cursor: pointer;
      position: absolute;
      z-index: 1000;
      top: 0px;
      left: -16px;
    }
    .dropdowntable {
      width: 100%;
      max-height: 200px !important;
      overflow: auto !important;
    }
  }
  .selectColumn {
    margin-bottom: 10px;
    height: auto;
  }
  .operationSpan {
    display: inline-block;
    width: 0.7rem;
    margin: 0 0.05rem;
    min-width: 40px;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    font-size: 12px;
    font-family: "MicrosoftYaHei";
    font-weight: 400;
  }
}
</style>

封装就到这里了,那怎么调用呢?

        <table-template
          :tableData="tableList" // 表格数据
          :tableColumns="listColumns" // 表头列数据
          :loading="loading"
          :selectionShow="false"
          :selectColumns="false"
          :headerBackColor="headerBackColor"
          :cellBackColor="cellBackColor"
          :cellBorderColor="cellBorderColor"
        ></table-template>

表格数据当然是后台获取,但是表头列数据可以后台获取,也可以前台定义,可以是这种格式:

tableColumns: [
        {
          key: "company",
          title: "企业",
          width: "150",
          isShow: true // 控制当前列是否显示
        },
        {
          key: "networkAccessRate",
          title: "入网率",
          width: "150",
          isShow: true
        },
        {
          key: "networkAccessScore",
          title: "入网率得分",
          width: "150",
          isShow: true
        },
        {
          key: "onlineRate",
          title: "上线率",
          width: "150",
          isShow: true
        },
        {
          key: "onlineScore",
          title: "上线率得分",
          width: "150",
          isShow: true
        },
        {
          key: "trackIntegrityRate",
          title: "轨迹完整率",
          width: "150",
          isShow: true
        }
      ]

 

Logo

前往低代码交流专区

更多推荐