table组件

2 篇文章 0 订阅
2 篇文章 0 订阅
<!--
* @description 表格组件
* @fileName TableList.vue
* @author Q
* @date 2021/05/15 15:13:45
-->
<template>
  <div class="table-container">
    <el-table v-if="showTable" ref="filterTable" :data="data" :show-summary="showSummary.show?showSummary.show:null" :summary-method="showSummary.show?summaryMethod:null" :sum-text="showSummary.sumText?showSummary.sumText:null" @filter-change="handleFilterChange" :border="border" :stripe="stripe" empty-text="暂无数据"
      style="width: 100%" :show-header="showHeader" :tooltip-effect="tooltipTheme" @selection-change="handleSelectionChange">
      <!-- 选择框列 -->
      <el-table-column v-if="selection" type="selection" :align="'center'"></el-table-column>
      <!-- 排序列 -->
      <el-table-column v-if="indexShow" width="100" label="序号" :align="'center'">
        <template slot-scope="scope">
          <div>
            <span>{{ scope.$index + 1 }}</span>
          </div>
        </template>
      </el-table-column>

      <template v-for="(item, index) in columns">
        <!-- 特殊列处理 -->
        <template v-if="item.render">
          <!-- visible 是否显示该列 -->
          <el-table-column v-if="item.visible" :filters="item.filters?item.filters:null" :column-key="item.prop" :key="index" :prop="item.prop ? item.prop : null" :align="item.align ? item.align : null" :fixed="item.fixed ? item.fixed : null" :label="item.label ? item.label : null"
            :show-overflow-tooltip="item.tooltip" :class-name="className"  :sortable="item.sortable ? item.sortable : false" :width="item.width ? item.width : null">
            <!-- 多级表头 -->
            <template v-if="item.children&&item.children.length>0">
              <div v-for="(item1, index1) in item.children" :key="index1">
                <el-table-column :key="index1" :filters="item.filters?item.filters:null" :column-key="item.prop" :prop="item1.prop ? item1.prop : null" :align="item1.align ? item1.align : null" :fixed="item1.fixed ? item1.fixed : null" :label="item1.label ? item1.label : null"
                  :show-overflow-tooltip="item1.tooltip" :class-name="className"  :sortable="item1.sortable ? item1.sortable : false" :width="item1.width ? item1.width : null">
                  <exSlot :render="item1.render" :row="scope.row" :index1="scope.$index" :column="item1" />
                </el-table-column>
              </div>
            </template>
            <!-- 不是多级表头 -->
            <template slot-scope="scope">
              <exSlot :render="item.render" :row="scope.row" :index="scope.$index" :column="item" />
            </template>
          </el-table-column>
        </template>

        <!-- 正常列 -->
        <template v-else>
          <!-- visible 是否显示该列 -->
          <el-table-column v-if="item.visible" :key="index" :column-key="item.prop" :filters="item.filters?item.filters:null" :prop="item.prop ? item.prop : null" :align="item.align ? item.align : null" :fixed="item.fixed ? item.fixed : null" :label="item.label ? item.label : null"
            :class-name="className"  :show-overflow-tooltip="item.tooltip" :sortable="item.sortable ? item.sortable : false" :width="item.width ? item.width : null">
            <!-- 多级表头 -->
            <template v-if="item.children&&item.children.length>0">
              <template v-for="(item1, index1) in item.children">
                <el-table-column  :prop="item1.prop ? item1.prop : null" :column-key="item.prop" :filters="item.filters?item.filters:null" :align="item1.align ? item1.align : null" :fixed="item1.fixed ? item1.fixed : null" :label="item1.label ? item1.label : null"
                  :show-overflow-tooltip="item1.tooltip" :class-name="className"  :sortable="item1.sortable ? item1.sortable : false" :width="item1.width ? item1.width : null">
                  <template slot-scope="scope">
                    <span v-html="formatter(scope.row[item1.prop])"></span>
                  </template>
                </el-table-column>
              </template>
            </template>
            <template slot-scope="scope">
              <!-- 字典处理 -->
              <template v-if="item.dict">
                <!-- 判断原始数据是否有效,有效转为字典数据,无效则转为--占位符 -->
                <span v-if="!scope.row[item.prop]" v-html="formatter(scope.row[item.prop])"></span>
                <dict-tag v-else :options="dict.type[item.prop]" :value="scope.row[item.prop]" />
              </template>
              <!-- 时间格式化 -->
              <span v-else-if="item.time">{{ parseTime(scope.row[item.prop],'{y}-{m}-{d}') }}</span>
              <!-- 不做处理 -->
              <span v-else v-html="formatter(scope.row[item.prop])"></span>
            </template>
          </el-table-column>
        </template>

      </template>

      <!-- 操作列 -->
      <el-table-column v-if="isEdit === true" label="操作" :align="'center'" width="200" :fixed="fixed">
        <template slot-scope="scope">
          <slot name="editSlot">
            <template>
              <el-button type="primary" @click="editClick(scope.row)">编辑</el-button>
              <el-button type="danger" @click="deleteClick(scope.row)">删除</el-button>
            </template>
          </slot>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination :style="{float:`${paginationPosition}`}" v-if="pagination" :background="background" :current-page.sync="currentPage" :page-size.sync="currentSize" :layout="layout" :page-sizes="pageSizes" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  </div>
</template>

<script>
// 自定义内容的组件
var exSlot = {
  functional: true,
  props: {
    row: Object,
    render: Function,
    index: Number,
    column: {
      type: Object,
      default: null
    }
  },
  // render 函数
  render: (h, context) => {
    const params = {
      row: context.props.row,
      index: context.props.index
    }
    if (context.props.columns) params.columns = context.props.columns
    return context.props.render(h, params)
  }
}
export default {
  name: 'TableList',
  components: { exSlot },
  props: {
    data: {
      type: Array,
      default: () => []
    },
    update: {
      type: Number,
      default: () => null
    },

    // 是否显示合计列
    showSummary: {
      type: Object,
      default: () => {
        return {
          show: false,
          sumText: '总计'
        }
      }
    },
    tooltipTheme: {
      type: String,
      default: 'dark'
    },
    // 是否显示表头
    showHeader: {
      type: Boolean,
      default: true
    }
    ,
    // 是否添加排序列
    indexShow: {
      type: Boolean,
      default: true
    },
    showTable: {
      type: Boolean,
      default: true
    },
    // 是否显示选择框列
    selection: {
      type: Boolean,
      default: false,
    },
    // 字段名
    columns: {
      type: Array,
      default: () => []
    },
    // 是否含有边框
    border: {
      type: Boolean,
      default: false
    },

    // 是否显示斑马条纹
    stripe: {
      type: Boolean,
      default: false
    },
    // 是否是可以编辑的表格
    isEdit: {
      type: Boolean,
      default: false
    },
    // 是否固定右侧一列,只对右侧操作栏起作用
    fixed: {
      type: String,
      default: 'right'
    },

    // 是否显示分页
    pagination: {
      type: Boolean,
      default: false
    },
    // 分页的位置
    paginationPosition: {
      type: String,
      default: 'center'
    },
    total: {
      required: false,
      type: Number
    },
    page: {
      type: Number,
      default: 1 // 默认第一页
    },
    limit: {
      type: Number,
      default: 10 // 默认每页20条
    },
    pageSizes: {
      type: Array,
      // default: [10, 20, 30, 50]
      default: function () {
        return [1, 2, 3, 5] // 默认显示可选的每页多少条数据
      }
    },
    layout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper'
    },
    background: {
      type: Boolean,
      default: true
    },
    autoScroll: {
      type: Boolean,
      default: true
    },
    hidden: {
      type: Boolean,
      default: false
    },
    className: {
      type: String,
      default: ''
    },
    render: {
      type: Function,
      default: function () { }
    }
  },
  data() {
    return {
      cloneColumns: []
    }
  },
  computed: {
    // 当前页多少条数据并且赋值给父组件
    currentPage: {
      get() {
        return this.page
      },
      set(val) {
        this.$emit('update:page', val)
      }
    },
    // 改变当前页几条数据得值赋值给父组件
    currentSize: {
      get() {
        return this.limit
      },
      set(val) {
        this.$emit('update:limit', val)
      }
    }
  },
  created() {
    this.cloneColumns = JSON.parse(JSON.stringify(this.columns))
  },
  watch: {
    columns(value) {
    }
  },
  mounted() { },

  methods: {
    // 自定义合计行
    summaryMethod(params) {
      const { columns, data } = params
      const sums = []
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '总计'
          return
        }
        const values = data.map(item => item[column.property]);
        let num = 0
        for (let i = 0; i < values.length; i++) {
          if (values[i]) {
            num += Number(values[i])
            sums[index] = num
          } else {
            if (isNaN(values[i])) {

            } else {
              num += Number(values[i])
              sums[index] = num
            }
          }
        }
        if (column.property === 'lv1Time' || column.property === 'lv2Time') {
          if (values.filter(Boolean).length === 0) {
            sums[index] = ''
          } else {
            let num = 0
            for (let i = 0; i < values.length; i++) {
              if (values[i]) {
                num += Number(values[i])
                sums[index] = num
              } else {
                if (isNaN(values[i])) {

                } else {
                  num += Number(values[i])
                  sums[index] = num
                }
              }
            }
          }
        }
      })
      let arr = []
      sums.map((i, index) => {
        if (index === 0) {
          arr.push(i)
        } else {
          if (!isNaN(i)) {
            arr.push(i)
          } else {
            arr.push('')
          }
        }

      })
      return arr

    },
    handleFilterChange(filters) {
      if (filters.length > 0) {
        this.$refs.filterTable.clearSelection();
        this.$refs.filterTable.toggleRowSelection(filters.pop());
      } else {
        this.columns.map((item) => {
          // 判断当前是那一列进行了筛选
          if (item.prop === Object.keys(filters)[0]) {
            item.filterValues = filters
          }
        })

        this.$emit('filtersParams', this.columns)
      }
    },
    // 当前行当前列数据是否有效,无效的话,返回--占位符
    formatter(row) {
      if(row){
      return isNaN(parseFloat(row)) && isFinite(row) ? '<span class="isNaN">--</span>' : row
      }else{
        return '<span class="isNaN">--</span>'
      }

    },
    /**
     * @param {*}
     * @return {*}
     * @author: 刘恋
     * @Date: 2021-09-01 11:56:37
     * @description: 已选的数据项
     */
    handleSelectionChange(val) {
      this.$emit('selectVal', val)
    },
    handleSizeChange(val) {
      this.pageSize = val
      this.$emit('pagination', { pageIndex: this.page, pageSize: val })
    },
    handleCurrentChange(val) {
      this.$emit('pagination', { pageIndex: val, pageSize: this.limit })
    },
    // 修改按钮的点击事件
    editClick(val) {
      this.$emit('edit', val)
    },
    // 删除按钮点击事件
    deleteClick(val) {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$emit('del', val)
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    }
  }

}
</script>

<style lang="scss">
.table-container {
  text-align: center;
  .el-pagination {
    margin-left: 0 !important;
    margin-top: 0 !important;
    background: #fff !important;
    height: 112px;
    line-height: 112px;
    display: flex;
    justify-content: center;
    align-items: center;
    ul {
      display: flex;
      justify-content: space-around;
      align-items: center;
      li {
        border-radius: 6px !important;
        color: #666666 !important;
      }
      .active {
        color: #fff !important;
        background: #1677ffff !important;
      }
    }
    button {
      border-radius: 6px !important;
      color: #666666 !important;
    }
  }
}
.table-container.el-table {
  margin-top: 20px;
}

.table-container .el-pagination {
  margin-top: 20px;
  margin-left: 20px;
}
.isNaN {
  color: red;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值