基于element的支持大部分场景公共表格

该代码段展示了一个使用Vue.js编写的多功能公共表格组件,支持多级表头、自定义样式、数据空时的占位提示、多选功能、序号、操作列等功能。组件还包含了排序、选择、操作按钮等交互,并提供了不同场景下的定制化操作栏,如组合管理、研究员全景等。
摘要由CSDN通过智能技术生成

支持大部分场景公共表格

在这里插入图片描述

HTML部分

<template>
  <div
    v-loading="tableLoading"
    class="ky-common-table"
    :element-loading-text="loadingText"
  >
    <el-table
      ref="commonTable"
      :key="updateTableKey"
      border
      highlight-current-row
      size="mini"
      header-cell-class-name="kf-common-table-header-style"
      :header-cell-style="setTableHeader"
      :cell-style="setCellStyle"
      :cell-class-name="cellClassName"
      :height="height"
      :max-height="maxHeight ? maxHeight : height"
      :data="tableData"
      :span-method="tableCellHandle"
      @sort-change="sortMethod"
      @selection-change="selectTable"
    >
      <!-- 数据为空的时候所占的数据 -->
      <template
        v-if="!tableData.length"
        slot="empty"
      >
        <div class="table-empty">
          <img
            src="../../assets/images/empty.png"
            alt="空数据占位图"
          >
          <div>暂无数据</div>
        </div>
      </template>
      <!-- 是否开启多选功能 -->
      <el-table-column
        v-if="isNeedSelection"
        type="selection"
        width="40"
        :show-overflow-tooltip="false"
        :selectable="setCheckBox"
      />
      <!-- 是否需要序号 -->
      <el-table-column
        v-if="isNeedIndex && tableHeaders.length"
        type="index"
        label="序号"
        align="center"
        fixed="left"
        width="50"
        :index="indexMethods"
        :resizable="false"
      />
      <!-- 循环生产表头 -->
      <template v-for="(item, index) in tableHeaders">
        <!-- 判断是否是多级表头,主要查看其中的children是否存在,且长度必须大于0 -->
        <k-table-column
          v-if="item[moreHeaderKey] && item[moreHeaderKey].length"
          :key="index"
          :more-header-key="moreHeaderKey"
          :item-data="item"
          :stock-name="stockName"
          :column-label="item.label"
          v-on="$listeners"
        />
        <!-- 单级表头 -->
        <el-table-column
          v-else
          :key="index"
          :show-overflow-tooltip="!item.isShrink"
          header-align="center"
          :label="item.label"
          :prop="item.prop"
          :width="item.width || 'auto'"
          :min-width="item.minWidth || ''"
          :fixed="item.fixed || false"
          :align="item.align || 'center'"
          :sortable="item.sortable || false"
          :resizable="false"
        >
          <!-- 是否开启自定义表头,isDefaultHearder -->
          <template
            v-if="item.isDefaultHearder"
            slot="header"
          >
            <span class="default-table-span">
              <span>{{ item.label }}</span>
              <span v-if="item.value">{{ item.value }}</span>
            </span>
            <el-tooltip
              v-if="item[notice]"
              class="item"
              effect="dark"
              :content="item[notice]"
              placement="top"
            >
              <em
                class="el-icon-info"
                style="margin-left: 5px;color: #2a76cd;cursor: pointer;"
              />
            </el-tooltip>
          </template>
          <template slot-scope="{ row, column }">
            <!-- 生成跳转链接 -->
            <el-link
              v-if="item.canCreateURL"
              type="primary"
            >
              {{ row[item.prop] }}
            </el-link>
            <!-- 普通文本--需要转千分位 -->
            <span v-else-if="item.isThousands">{{ row[item.prop] | moneyThousands }}</span>
            <!-- 将多行的内容,展示出隐藏按钮 -->
            <div
              v-else-if="item.isShrink"
              class="shrink-area"
            >
              <!-- 当数组数量正好小于、等于10时,展示所有的内容 -->
              <template v-if="row[column.property].length <= 10">
                <template v-for="val in row[stockName]">
                  <span
                    :key="val.code"
                    class="stock-item"
                  >{{ val.name }}</span>
                </template>
              </template>
              <!-- 当数组数量大于10时,展示9个内容,最后一个为一个收缩标 -->
              <template v-if="row[column.property].length > 10">
                <template v-for="(val, idx) in row[stockName]">
                  <span
                    v-show="idx < 9"
                    :key="idx"
                    class="stock-item"
                  >{{ val.name }}</span>
                </template>
                <el-popover
                  trigger="hover"
                  placement="right"
                  popper-class="popover-default-style"
                  class="default-popover"
                >
                  <div class="list-area">
                    <span
                      v-for="val in row[stockName].slice(9)"
                      :key="val.code"
                      class="popover-item"
                    >{{ val.name }}</span>
                  </div>
                  <el-button
                    slot="reference"
                    class="shrink"
                    size="mini"
                  >
                    +{{ row[stockName].length - 9 }}
                  </el-button>
                </el-popover>
              </template>
            </div>
            <!-- 控制文本颜色,如果文本是数字(有%号)的时候,大于0是红色,小于0是绿色 -->
            <span
              v-else-if="!item.stopStyle && row[item.prop] && row[item.prop].toString().includes('%') && Number(row[item.prop].slice(0, row[item.prop].length - 1))"
              :style="{ color: row[item.prop].toString().includes('-') ? '#388B0A' : '#C1362C' }"
            >{{ row[item.prop] }}</span>
            <!-- 普通文本 -->
            <span v-else>{{ row[item.prop] }}</span>
          </template>
        </el-table-column>
      </template>
      <!-- 操作 -->
      <el-table-column
        v-if="isNeedControl"
        fixed="right"
        label="操作"
        align="center"
        :width="width"
        :resizable="false"
      >
        <template slot-scope="scope">
          <!-- 组合全景 -->
          <template v-if="controlType === 'combination'">
            <el-button
              v-if="isNeedDetail"
              type="text"
              style="font-size: 14px"
              @click="watchDetail(scope)"
            >
              详情
            </el-button>
            <el-button
              v-if="isNeedCopy"
              type="text"
              style="font-size: 14px"
              @click="copyData(scope)"
            >
              复制
            </el-button>
            <el-button
              v-if="isNeedAdustment"
              type="text"
              style="font-size: 14px"
              @click="adjustmentData(scope)"
            >
              调仓
            </el-button>
            <el-popover placement="bottom-end">
              <p style="font-size: 16px;color: #3C4455;font-weight: 700;">
                {{ promptTitle }}
              </p>
              <p style="font-size: 14px;color: #3C4455;margin: 4px 0 12px">
                {{ promptDescription }}
              </p>
              <div style="text-align: right; margin: 0">
                <el-button
                  size="mini"
                  class="cancel"
                  style="font-size: 14px"
                  @click="cancelDeletion"
                >
                  取消
                </el-button>
                <el-button
                  type="primary"
                  size="mini"
                  style="background: #2A76CD;border-color: #2A76CD"
                  @click="deleteData(scope)"
                >
                  确定
                </el-button>
              </div>
              <el-button
                v-if="isNeedDelete && isNeedWindowDelete !== true"
                slot="reference"
                type="text"
                style="margin: 0 8px;font-size: 14px"
              >
                删除
              </el-button>
            </el-popover>
            <el-button
              v-if="isNeedStop"
              type="text"
              :disabled="!scope.row.isShowStop"
              :class="{showGray: !scope.row.isShowStop}"
              style="font-size: 14px"
              @click="stopData(scope)"
            >
              停用
            </el-button>
            <el-button
              v-if="isNeedEnable"
              type="text"
              :disabled="!scope.row.isShowStart"
              :class="{showGray: !scope.row.isShowStart}"
              style="font-size: 14px"
              @click="enableData(scope)"
            >
              启用
            </el-button>
          </template>
          <!-- 研究员全景 -->
          <template v-if="controlType === 'researcher'">
            <el-button
              v-if="isNeedDetail"
              type="text"
              style="font-size: 14px"
              @click="watchDetail(scope)"
            >
              详情
            </el-button>
          </template>
          <!-- 金股推荐 -->
          <template v-if="controlType === 'stockRecommend'">
            <el-button
              v-if="isNeedSee"
              type="text"
              style="font-size: 14px"
              @click="seeData(scope)"
            >
              查看
            </el-button>
            <el-button
              v-if="isNeedModify"
              type="text"
              style="font-size: 14px"
              :disabled="scope.row.displayType === '1'"
              :class="{showGray: scope.row.displayType === '1'}"
              @click="modifyData(scope)"
            >
              修改
            </el-button>
            <el-popover placement="bottom-end">
              <p style="font-size: 16px;color: #3C4455;font-weight: 700;">
                {{ promptTitle }}
              </p>
              <p style="font-size: 14px;color: #3C4455;margin: 4px 0 12px">
                {{ promptDescription }}
              </p>
              <div style="text-align: right; margin: 0">
                <el-button
                  size="mini"
                  class="cancel"
                  style="font-size: 14px"
                  @click="cancelDeletion"
                >
                  取消
                </el-button>
                <el-button
                  type="primary"
                  size="mini"
                  style="background: #2A76CD;border-color: #2A76CD;font-size: 14px"
                  @click="deleteData(scope)"
                >
                  确定
                </el-button>
              </div>
              <el-button
                v-if="isNeedWindowDelete && isNeedDelete !== true"
                slot="reference"
                type="text"
                style="margin: 0 8px;font-size: 14px"
                :disabled="scope.row.displayType === '1'"
                :class="{showGray: scope.row.displayType === '1'}"
              >
                删除
              </el-button>
            </el-popover>
            <el-button
              v-if="isNeedSubmit"
              type="text"
              style="font-size: 14px"
              :disabled="scope.row.displayType === '1'"
              :class="{showGray: scope.row.displayType === '1'}"
              @click="submitData(scope)"
            >
              提交
            </el-button>
          </template>
          <!-- 行业组合推荐 -->
          <template v-if="controlType === 'industryRecommend'">
            <el-button
              v-if="isNeedDetail"
              type="text"
              style="font-size: 14px"
              @click="watchDetail(scope)"
            >
              详情
            </el-button>
            <el-button
              v-if="isNeedCopy"
              type="text"
              style="font-size: 14px"
              @click="copyData(scope)"
            >
              复制
            </el-button>
            <el-button
              v-if="isNeedAdustment"
              type="text"
              :class="{showGray: !scope.row.isShowStop}"
              :disabled="!scope.row.isShowStop"
              style="font-size: 14px"
              @click="adjustmentData(scope)"
            >
              调仓
            </el-button>
            <el-popover placement="bottom-end">
              <p style="font-size: 16px;color: #3C4455;font-weight: 700;">
                {{ promptTitle }}
              </p>
              <p style="font-size: 14px;color: #3C4455;margin: 4px 0 12px">
                {{ promptDescription }}
              </p>
              <div style="text-align: right; margin: 0">
                <el-button
                  size="mini"
                  class="cancel"
                  @click="cancelDeletion"
                >
                  取消
                </el-button>
                <el-button
                  type="primary"
                  size="mini"
                  style="background: #2A76CD;border-color: #2A76CD;"
                  @click="deleteData(scope)"
                >
                  确定
                </el-button>
              </div>
              <el-button
                v-if="isNeedDelete && isNeedWindowDelete !== true"
                slot="reference"
                type="text"
                style="margin: 0 8px;font-size: 14px"
              >
                删除
              </el-button>
            </el-popover>
            <el-button
              v-if="isNeedStop"
              type="text"
              :disabled="!scope.row.isShowStop"
              :class="{showGray: !scope.row.isShowStop}"
              style="font-size: 14px"
              @click="stopData(scope)"
            >
              停用
            </el-button>
            <el-button
              v-if="isNeedEnable"
              type="text"
              :disabled="!scope.row.isShowStart"
              :class="{showGray: !scope.row.isShowStart}"
              style="font-size: 14px"
              @click="enableData(scope)"
            >
              启用
            </el-button>
          </template>
          <!-- 券商行业组合 -->
          <template v-if="controlType === 'stockIndustryCombination'">
            <el-button
              v-if="isNeedDetail"
              type="text"
              style="font-size: 14px"
              @click="watchDetail(scope)"
            >
              详情
            </el-button>
          </template>
          <!-- 券商金股组合 -->
          <template v-if="controlType === 'stockGoldCombination'">
            <el-button
              v-if="isNeedDetail"
              type="text"
              style="font-size: 14px"
              @click="watchDetail(scope)"
            >
              详情
            </el-button>
          </template>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <el-pagination
      v-show="tableData.length && isShowPagination"
      small
      background
      popper-class="page-paging"
      layout="total, sizes, prev, pager, next, jumper"
      :page-sizes="pageSizes"
      :page-size="pageSize"
      :total="totalSize"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

js部分

<script>
import KTableColumn from "@/components/KCommonTable/KTableColumn";
import { numberFilter } from "@/utils/validate";
import { mapGetters } from "vuex";
import store from '../../store'

export default {
  name: 'KCommonTable',
  components: {
    KTableColumn,
  },
  filters: {
    /** 奖金额装成千分位 */
    moneyThousands (value) {
      let result = ''
      result = Number(value) ? numberFilter(value) : value
      return result
    },
  },
  props: {
    showFirstIndex: { // 第一行是否需要展示序号
      type: Boolean,
      default: true,
    },
    height: { // 表格的高股
      type: Number,
      default: 487,
    },
    width: {
      type: String,
      default: "100px",
    },
    maxHeight: { // 表格的最大的高度
      type: Number,
    },
    isNeedIndex: { // 是否需要序号
      type: Boolean,
      default: false,
    },
    isNeedSelection: { // 是否需要开启多选
      type: Boolean,
      default: false,
    },
    tableHeaders: { // 表格的头部列表
      type: Array,
      default() {
        return [];
      },
    },
    tableData: { // 表格数据集合
      type: Array,
      default() {
        return [];
      },
    },
    notice: { // 表头tooltip字段名称
      type: String,
      default: "notice",
    },
    stockName: { // 多行隐藏列表名称
      type: String,
      default: "stockName",
    },
    tableLoading: { // 表格loading效果
      type: Boolean,
      default: false,
    },
    loadingText: {
      type: String,
      default: "加载中...",
    },
    isNeedControl: { // 是否需要操作栏
      type: Boolean,
      default: true,
    },
    isNeedDetail: { // 展示详情按钮
      type: Boolean,
      default: false,
    },
    isNeedCopy: { // 展示复制按钮
      type: Boolean,
      default: false,
    },
    isNeedAdustment: { // 展示调仓按钮
      type: Boolean,
      default: false,
    },
    isNeedStop: { // 展示停用按钮
      type: Boolean,
      default: false,
    },
    isNeedSee: { // 展示查看按钮
      type: Boolean,
      default: false,
    },
    isNeedModify: { // 展示修改按钮
      type: Boolean,
      default: false,
    },
    isNeedDelete: { // 展示删除按钮
      type: Boolean,
      default: false,
    },
    isNeedWindowDelete: { // 无弹窗删除
      type: Boolean,
      default: false,
    },
    isNeedEnable: { // 展示启用按钮
      type: Boolean,
      default: false,
    },
    isNeedSubmit: { // 展示提交按钮
      type: Boolean,
      default: false,
    },
    isNeedMergeTable: { // 是否需要合并表格处理
      type: Boolean,
      default: false,
    },
    mergeSpanRow: { // 合并的行数
      type: Array,
      default() {
        return []
      },
    },
    totalSize: { // 总条数
      type: Number,
      default: 0,
    },
    mergeColumn: { // 需要合并的列
      type: String,
      default: "",
    },
    pageSizes: { // 每页显示条数的数据集合
      type: Array,
      default() {
        return [10, 20, 30, 40];
      },
    },
    pageSize: { // 每页显示的条数
      type: Number,
      default: 10,
    },
    currentPageNums: { // 当前页数
      type: Number,
      default: 1,
    },
    isShowPagination: { // 是否显示分页器
      type: Boolean,
      default: true,
    },
    threeLayerPrompt: { // 是否需要第二句提示语
      type: Boolean,
      default: false,
    },
    promptTitle: {
      type: String,
      default: "请确认是否删除组合?",
    },
    promptDescription: {
      type: String,
      default: "删除后将无法再看到组合信息及组合持仓。",
    },
    checkBoxArr: { // 已选数组集合
      type: Array,
      /** 设置数组集合 */
      default() {
        return [];
      },
    },
    typeId: { // 研究员全景参数
      type: Number,
      default: 0,
    },
    controlType: { // 操作列表样式
      type: String,
      default: "",
    },
    moreHeaderKey: { // 多级表头的标识
      type: String,
      default: "children",
    },
  },
  /** 初始化参数 */
  data() {
    return {
      setTableHeader: { // 表头参数
        backgroundColor: "#f3f4f6",
        fontSize: "14px",
        color: "#3C4455",
        textAlign: "center",
        lineHeight: "20px",
        fontweight: 700,
        height: "40px",
        padding: "0",
      },
      userName: '', // 登录用户名
      updateTableKey: Math.random(), // 表格唯一标识
    };
  },
  /** 更新数据 */
  updated() {
    // myTable是表格的ref属性值
    if (this.$refs.commonTable && this.$refs.commonTable.doLayout) {
      this.$refs.commonTable.doLayout();
    }
  },
  methods: {
    /** 表格序号设置 */
    indexMethods(index) {
      let result = "";
      if (index !== 0 && !this.showFirstIndex) {
        result = (this.currentPageNums - 1) * this.pageSize + index;
      } else if (this.showFirstIndex) {
        result = (this.currentPageNums - 1) * this.pageSize + index + 1;
      }
      return result;
    },
    /** 设置表格单元格样式 */
    setCellStyle({
                   row,
                   rowIndex,
                 }) {
      let resultClass = {};
      let isTotal = false; // 是否有【合计】
      isTotal = Object.values(row)
        .includes("合计");
      // 大于0是红色,小于0是绿色
      // if (value && value.includes('%') && Number(value.slice(0, value.length - 1)) && !isTotal) {
      //   resultClass = value.includes('-') ? { color: '#388B0A' } : { color: '#C1362C' }
      // } else {
      //
      // }
      resultClass = {
        color: "#3C4455",
      };
      // 如果行数据里面有【合计】且是在第一行时,显示主题颜色
      if (isTotal && rowIndex === 0) {
        resultClass = { color: "#2a76cd" };
      }
      resultClass.height = "34px";
      resultClass.padding = "0";
      resultClass.fontSize = "14px";
      return resultClass;
    },
    /** 组合状态样式设置 */
    cellClassName({
                    row,
                    column,
                  }) {
      const value = row[column.property];
      const label = column.property;
      let cellClassName = "";
      if (label && label === "IS_ENABLE" && value && (value.includes("启用") || value.includes("停用"))) {
        cellClassName = value.includes("启用") ? "enable" : "deactivate";
      }
      if (label && label === "status" && value && (value.includes("未提交") || value.includes("已提交"))) {
        cellClassName = value.includes("未提交") ? "not-submitted" : "submitted";
      }
      return cellClassName;
    },
    /** 详情 */
    watchDetail({ row }) {
      this.$emit("watchDetail", row);
    },
    /** 复制 */
    copyData({ row }) {
      this.$emit("copyData", row);
    },
    /** 调仓 */
    adjustmentData({ row }) {
      this.$emit("adjustmentData", row);
    },
    /** 查看 */
    seeData({ row }) {
      this.$emit("seeData", row);
    },
    /** 修改 */
    modifyData({ row }) {
      this.$emit("modifyData", row);
    },
    /** 删除 */
    deleteData({ row }) {
      this.$emit("deleteData", row);
      document.body.click();
    },
    /** 停用 */
    stopData({ row }) {
      this.$emit("stopData", row);
    },
    /** 启用 */
    enableData({ row }) {
      this.$emit("enableData", row);
    },
    /** 提交 */
    submitData({ row }) {
      this.$emit("submitData", row);
    },
    /** 改变每页显示条数 */
    handleSizeChange(val) {
      this.$emit("handleSizeChange", val);
    },
    /** 改变当髂内页数 */
    handleCurrentChange(val) {
      this.$emit("handleCurrentChange", val);
    },
    /** 重新渲染表格 */
    resetHandle() {
      this.$refs.commonTable.doLayout();
    },
    /** 排序 */
    sortMethod(sortValue) {
      this.$emit("sortMethods", sortValue);
    },
    /** 取消删除 */
    cancelDeletion() {
      document.body.click();
    },
    /** 设置多选框是否能选择 */
    setCheckBox(row) {
      return !this.checkBoxArr.includes(row.stockCode) && row.isAsh === "0";
    },
    /** 当表格多选时触发的变化 */
    selectTable(data) {
      const selectArr = data.map(item => item.stockCode);
      this.$emit("selectChange", selectArr);
    },
    /** 合并单元格除数 */
    tableCellHandle({
                      rowIndex,
                      column,
                    }) {
      if (this.isNeedMergeTable) {
        if (column.property === this.mergeColumn) {
          const result = {
            rowspan: 0,
            colspan: 0,
          };
          if (this.mergeSpanRow[rowIndex]) {
            result.rowspan = this.mergeSpanRow[rowIndex];
            result.colspan = 1;
          }
          return result;
        }
      }
    },
    /** 更新表格 */
    updateTableData() {
      this.updateTableKey = Math.random();
    },
  },
  computed: {
    ...mapGetters(['userIdentity']),
  },
  mounted() {
    this.userName = store.state.user.userInfo.name || ''
  },
};
</script>

scss

<style scoped lang="scss">
.ky-common-table {
  width: 100%;

  .shrink-area {
    display: flex;
    align-items: center;
    flex-wrap: wrap;

    .stock-item {
      display: inline-block;
      text-align: center;
      width: 20%;
      padding: 2px 3px;
    }

    span:last-child {
      display: inline-block;
      width: 20%;
    }

    .el-button {
      margin-bottom: 8px;
      width: 50px;
      height: 20px;
      background: #E8F7FF;
      border-radius: 3px;
      color: #2A76CD;
      border: none;
      line-height: 20px;
      padding: 0;
    }
  }

  .el-pagination {
    margin: 14px 0;
  }
}
</style>
<style lang="scss">
.ky-common-table {
  .el-button--small {
    color: #2A76CD;

    &:focus,
    &:hover {
      border-color: transparent;
      background-color: transparent;
    }
  }

  .el-table__cell {
    padding: 4px 0;
    &:last-child {
      padding: 0;
    }
  }

  .el-button--small.is-disabled.showGray {
    color: rgb(192, 196, 204)
  }

  .commonStyle {
    display: inline-block;
    width: 46px;
    height: 25px;
    line-height: 25px;
    font-size: 14px;
    box-sizing: border-box;
    border-radius: 50px;
  }

  .enable {
    span {
      @extend .commonStyle;
      border: 1px solid #1199AD;
      color: #1199AD;
      background: rgb(226, 243, 245);
    }
  }

  .deactivate {
    span {
      @extend .commonStyle;
      border: 1px solid #D69C15;
      color: #D69C15;
      background: rgb(250, 243, 227);
    }
  }

  .commonSubmitStyle {
    display: inline-block;
    width: 52px;
    height: 24px;
    line-height: 24px;
    font-size: 14px;
    text-align: center;
    box-sizing: border-box;
    border-radius: 3px;
  }

  .not-submitted {
    span {
      @extend .commonSubmitStyle;
      background: #EAEBEB;
      color: #3C4455;
    }
  }

  .submitted {
    span {
      @extend .commonSubmitStyle;
      background: #E8F7FF;
      color: #2A76CD;
    }
  }

  tbody {
    td {
      .cell {
        width: 100% !important;
      }
    }
  }
}

.industry-combination,
.broker-gold-money,
.researcherPanorama {
  el-table__header {
    th.el-table__cell {
      padding: 6px 0;
    }
  }
}

.el-popper {
  .el-button--mini.cancel {
    &:focus,
    &:hover {
      background: #FFFFFF;
      border-color: #2A76CD;
      color: #2A76CD;
    }
  }
}

.deactivate-combination,
.el-popover.el-popper {
  .el-button--mini {
    width: 44px;
    height: 22px;
    padding: 0;
  }
}

.compositePanorama,
.researcherPanorama {
  .composite-panorama {
    margin-top: 24px;
    .el-table {
      .el-table__header-wrapper,
      .el-table__body-wrapper {
        .el-table__cell {
          padding: 0;
        }
      }
    }
  }
}

.el-table__body tr.current-row > td {
  background: rgb(245, 247, 250) !important;
}

// 解决表头错位问题
.el-table th.gutter {
  display: table-cell !important;
}

.popover-default-style {
  width: 200px;

  .list-area {
    display: flex;
    align-items: center;
    flex-wrap: wrap;

    .popover-item {
      display: inline-block;
      width: 50%;
      text-align: center;
    }
  }
}

.combinationGlance-content {
  .gold-share-list {
    .el-table__header-wrapper {
      .cell {
        display: flex !important;
        justify-content: center;
        align-items: center;

        .default-table-span {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
        }
      }
    }
  }
}
</style>

子表格

<template>
  <el-table-column class="ky-table-column" :label="columnLabel">
    <template v-for="(item, index) in itemData[moreHeaderKey]">
      <!-- 判断是否是多级表头,主要查看其中的children是否存在,且长度必须大于0 -->
      <template v-if="item[moreHeaderKey] && item[moreHeaderKey].length">
        <KTableColumn
                :key="index"
                :more-header-key="moreHeaderKey"
                :item-data="item"
                :stock-name="stockName"
                :column-label="item.label"
        />
      </template>
      <!-- 单级表头 -->
      <el-table-column
              v-else
              :key="index"
              :label="item.label"
              :width="item.width || 'auto'"
              :fixed="item.fixed || false"
              :align="item.align || 'center'"
      >
        <!-- 是否开启自定义表头,isDefaultHearder -->
        <template v-if="item.isDefaultHearder" slot="header">
          <span>{{ item.label }}</span>
          <el-tooltip class="item" effect="dark" :content="itemData[notice]" placement="top">
            <em class="el-icon-info" style="margin-left: 5px;color: #2a76cd;cursor: pointer;"></em>
          </el-tooltip>
        </template>
        <template slot-scope="{ row, column }">
          <!-- 生成跳转链接 -->
          <el-link v-if="item.canCreateURL && row[item.prop] !== '--' && row[item.prop] !== ''" type="primary"
                   @click="clickUrl(row,item)">
            {{
              row[item.prop]
            }}
          </el-link>
          <!-- 普通文本--需要转千分位 -->
          <span v-else-if="item.isThousands">{{ row[item.prop] | moneyThousands }}</span>
          <!-- 将多行的内容,展示出隐藏按钮 -->
          <div v-else-if="item.isShrink" class="shrink-area">
            <!-- 当数组数量正好小于、等于10时,展示所有的内容 -->
            <template v-if="row[column.property].length <= 10">
              <template v-for="val in row[stockName]">
                <span class="stock-item" :key="val.code">{{ val.name }}</span>
              </template>
            </template>
            <!-- 当数组数量大于10时,展示9个内容,最后一个为一个收缩标 -->
            <template v-if="row[column.property].length > 10">
              <template v-for="(val, idx) in row[stockName]">
                <span v-show="idx < 9" class="stock-item" :key="idx">{{ val.name }}</span>
              </template>
              <el-popover
                      trigger="hover"
                      placement="right"
                      popper-class="popover-default-style"
              >
                <div class="list-area">
                  <span v-for="val in row[stockName].slice(9)" :key="val.code" class="popover-item">{{
                      val.name
                    }}</span>
                </div>
                <el-button class="shrink" slot="reference" size="mini">+{{ row[stockName].length - 9 }}</el-button>
              </el-popover>
            </template>
          </div>
          <!-- 普通文本 -->
          <span v-else :class="judgeColor(row, item)">{{ row[item.prop] }}</span>
        </template>
      </el-table-column>
    </template>
  </el-table-column>
</template>

js部分

<script>
import { numberFilter } from '@/utils/validate'

export default {
  name: 'KTableColumn',
  props: {
    itemData: { // 表格每一项的数据集合
      type: Object,
      default () {
        return {}
      },
    },
    notice: { // 表头tooltip字段名称
      type: String,
      default: 'notice',
    },
    stockName: { // 多行隐藏列表名称
      type: String,
      default: 'stockName',
    },
    moreHeaderKey: { // 多级表头的标识
      type: String,
      default: 'children',
    },
    columnLabel: { // 表格列展示的label
      type: String,
      default: '',
    },
  },
  methods: {
    /**
     * 点击链接跳转按钮
     */
    clickUrl (row, item) {
      this.$emit('clickUrl', row, item)
    },
    judgeColor (row, item) {
      if (row[item.prop].includes('%') && Number(row[item.prop].slice(0, row[item.prop].length - 1))) {
        if (!row[item.prop].includes('-')) {
          return 'upStyle'
        }
        return 'downStyle'
      }
      return ''
    },
  },
  filters: {
    /** 奖金额装成千分位 */
    moneyThousands (value) {
      let result = ''
      result = Number(value) ? numberFilter(value) : value
      return result
    },
  },
}
</script>

scss

<style lang="scss">
.upStyle {
  color: #C1362C;
}

.downStyle {
  color: #388B0A;
}
</style>

numberFilter

/** 数字转为千分位,并保留两个小数位 */
export function numberFilter (data) { // 例(123456.78)
  let dataValue = ''
  if ((typeof data === 'string' || typeof data === 'number') && Number(data)) {
    dataValue = Number(data)
  }
  if (data && Number(dataValue)) {
    const newNum = dataValue.toLocaleString('en-US', { minimumFractionDigits: 2 }) // 数字转成千分位 = 123,456.78
    return newNum
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值