vue表格封装

<template>
  <div class="table-container">
    <div class="table-box"> 
      <el-table
        class="table-height"
        highlight-current-row
        v-loading="loading"
        :data="tableData" fit 
        :height="tableHeight"
        :header-cell-style="headerStyle"
        style="width: 100%" @row-click="rowClick" @selection-change="handleSelectionChange">
        <el-table-column v-if="indexShow" type="index" align="center" label="序号">
        </el-table-column>
        <el-table-column v-if="isCheck" type="selection" align="center" :selectable="selectable" fixed>
        </el-table-column>
        <el-table-column v-for="(item, index) in tableHeader"
          :key="index"
          :label="item.label"
          :prop="item.prop"
          :sortable="item.oper || item.switch ? false : true"
          :fixed="item.fixed"
          :width="item.width"
          :show-overflow-tooltip="showOverflowTooltip"
          align="center">
          <template slot-scope="scope">
            <span v-if="item.oper">
              <el-button v-for="(o, index) in item.oper"
                v-hasBtn="o.hasBtn && typeof o.hasBtn == 'function' ? o.hasBtn(scope.row) : o.hasBtn"
                v-show="o.isShowFun && typeof o.isShowFun == 'function' ? o.isShowFun(scope.row) : true"
                :key="index"
                :type="o.style"
                :icon="o.icon"
                :disabled="!o.disBtnFun ? (scope.row[o['prop']] == 1) : o.disBtnFun(scope.row)"
                @click="o.clickFun(scope.row, scope.$index, tableData)"
                size="small">
                <template v-if="!o.formatDatas">{{ o.name }}</template>
                <template v-else>
                  {{ o.formatDatas(scope.row) }}
                </template>
              </el-button>
            </span>
            <span v-if="item.switch">
              <el-switch v-for="(o, index) in item.switch"
                :key="index" @change="o.clickFun($event, scope.row)"
                class="switchStyle"
                :disabled="o.disSwitchFun ? o.disSwitchFun(scope.row) : false"
                :active-value="scope.row[o['prop']] > 1 || scope.row[o['prop']] < 0 ? scope.row[o['prop']] : o.activeValue ? o.activeValue(scope.row) : o.active"
                :inactive-value="scope.row[o['prop']] > 1 || scope.row[o['prop']] < 0 ? scope.row[o['prop']] : o.inactiveValue ? o.inactiveValue(scope.row) : o.inactive"
                :active-text="o.activeText ? o.activeText(scope.row) : o.text"
                :inactive-text="o.inactiveText ? o.inactiveText(scope.row) : o.intext"
                :active-color="o.activeColor ? o.activeColor : '#13ce66'"
                :inactive-color="o.inactiveColor ? o.inactiveColor : '#ff4949'"
                v-model="scope.row[o['prop']]"
                size="small"
              >
              </el-switch>
            </span>
            <!--formatData:自定义过滤器-->
            <template v-else>
              <template v-if="!item.formatDatas && !item.isEdit">{{ scope.row[item.prop] }}</template>
              <template v-else-if="item.isEdit && item.inputType">
                <el-input 
                  v-if="item.inputType === 'input'"
                  v-show="scope.row.editFlag"
                  v-model="scope.row[item.prop]"
                  maxlength="50"
                  :placeholder="'请输入'+item.label">
                </el-input>
                <el-select
                  v-show="scope.row.editFlag"
                  v-if="item.inputType === 'select'"
                  v-model="scope.row[item.prop]" 
                  placeholder="请选择">
                  <el-option
                    v-for="k in (typeof item.options == 'function' && item.options(scope.row) || [])"
                    :key="k.value"
                    :label="k.label"
                    :value="k.value">
                  </el-option>
                </el-select>
                <el-date-picker
                  v-show="scope.row.editFlag"
                  v-if="item.inputType === 'date'"
                  v-model="scope.row[item.prop]"
                  :valueFormat="scope.row.valueFormat"
                  :format="scope.row.format"
                  type="date"
                  placeholder="请选择日期">
                </el-date-picker>
                <span v-show="!scope.row.editFlag">
                  {{ item.formatDatas ? item.formatDatas(scope.row) : scope.row[item.prop] }}
                </span>
              </template>
              <template v-else>
                {{ scope.row | formatters(item.formatDatas) }}
              </template>
            </template>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="page-box">
      <pub-pagination v-if="pageFlag" class="right page-height"
        :total="total"
        :currentPage="pagesize"
        :pageSizes="pageSizes"
        :pageSize="limit"
        :layout="layout"
        @handleSizeChange="handleSizeChange"
        @handleCurrentChange="handleCurrentChange">
      </pub-pagination>
    </div>
  </div>
</template>

<script>
import PubPagination from './p-pagination'
export default {
  components: {
    PubPagination
  },
  props: {
    // 是否初始化调用initData
    isInitFlag: {
      type: Boolean,
      default: true
    },
    // 是否通过接口获取数据
    isApiFlag: {
      type: Boolean,
      default: true
    },
    dataList: {
      type: Array,
      default: ()=>[]
    },
    // 表格高度
    tableHeight: {
      type: String,
      default: '100%'
    },
    // 表格头部字段
    tableHeader: {
      type: Array,
      default: function() {
        return [];
      }
    },
    headerStyle: {
      type: Function,
      default: function() {
        return {
          background:'#eef1f6',
          color:'#606266'
        }
      }
    },
    // 复选框列flag
    isCheck: {
      type: Boolean,
      default: false
    },
    // 序号列flag
    indexShow: {
      type: Boolean,
      default: false
    },
    // 接口
    api: {
      type: Function,
      default: ()=>{}
    },
    pageFlag: {在这里插入代码片
      type: Boolean,
      default: true
    },
    // 分页layout
    layout: {
      type: String,
      default: 'slot, prev, pager, next, sizes, jumper'
    },
    // 绑定复选框prop
    isDisCheck: {
      type: Function,
      default: () => {}
    },
    // 个数选择器
    pageSizes: {
      type: Array,
      default: () => {
        return [10, 20]
      }
    },
    // 是否超出省略
    showOverflowTooltip: {
      type: Boolean,
      default: () => {
        return true
      }
    }
  },
  created() {
    if(!this.pageFlag) {
      this.limit = 999;
    }

    this.limit = this.pageSizes[0];

    this.initData();
    // console.log(this.tableHeight);
  },
  filters: {
    formatters(val, func) {
      if(typeof func !== 'function') {
        return val;
      }
      return func(val);
    }
  },
  data () {
    return {
      tableData: [],
      limit: 10, // 每页条数
      pagesize: 1, // 页码
      // pageSizes: [10, 20],
      total: 0,
      loading: true, // 表格加载状态
      queryParams: {} // 查询条件
    };
  },
  watch: {
    dataList: {
      handler(n, o) {
        this.tableData = n;
      },
      deep: true
    }
  },
  methods: {
    initData() { // 初始化数据
      if(!this.isApiFlag) {
        this.loading = false;
        this.tableData = this.dataList;
        return;
      }
      if (this.isInitFlag) {
        this.loading = true;
        this.api({
          "pageNum": this.pagesize,
          "pageSize": this.limit
        }).then(res=> {
          this.loading = false;
          let data = res && res.data;
          this.$emit('dataformat', data)
          this.tableData = data.list;
          this.total = data.total;
          if (data.total == 0) {
            this.pagesize = 0;
          }
        }).catch(err=> {
          this.loading = false;
        })
      } else {
        this.loading = false;
      }
    },
    queryTable(obj) { // 查询条件
      this.queryParams = obj;
      this.resetPage();
      this.updateList();
    },
    resetTable() {
      // 重置条件
      this.queryParams = {};
      this.resetPage();
      this.updateList();
    },
    resetPage() { // 重置页码
      if(!this.pageFlag) {
        this.limit = 999;
        this.pagesize = 1;
        return;
      }
      this.pagesize = 1;
      
      this.limit = this.pageSizes[0];
    },
    updateList() { // 更新数据
      let params = Object.assign({
        "pageNum": this.pagesize,
        "pageSize": this.limit
      }, this.queryParams);
      this.loading = true;
      this.api(params).then((res)=> {
        this.loading = false;
        let data = res && res.data;
        this.$emit('dataformat', data)
        this.tableData = data.list;
        this.total = data.total;
        if (data.total == 0) {
          this.pagesize = 0;
        }
      }).catch(err=> {
        this.loading = false;
      })
    },
    rowClick(val) { // 行点击事件
      this.$emit('rowClick', val);
    },
    handleSelectionChange(val) { // 选择的内容
      this.$emit('selectData', val);
    },
    handleSizeChange(val) { // 每页多少条
      this.limit = val;
      this.updateList();
    },
    handleCurrentChange(val) { // 当前页码
      this.pagesize = val;
      this.updateList();
    },
    selectable(row, index) {
      let flag = this.isDisCheck(row);
      if (flag) {
        return false;
      } else {
        return true;
      }
    }
  }
}
</script>
<style lang='less' scoped>
  /deep/ .switchStyle .el-switch__label {
    position: absolute;
    display: none;
    color: #fff;
  }
  /deep/ .switchStyle .el-switch__label--left {
    z-index: 9;
    left: 10px;
  }
  /deep/ .switchStyle .el-switch__label--right {
    z-index: 9;
    left: -2px;
  }
  /deep/ .switchStyle .el-switch__label.is-active {
    display: block;
  }
  /deep/ .switchStyle.el-switch .el-switch__core,
  .el-switch .el-switch__label {
    width: 70px !important;
  }
  .table-container {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
    border-radius: 20px;
    & > .table-box {
      height: 91% !important;
      padding: 12px 23px 0 23px;
      /deep/ .el-table td {
        padding: 8px 0;
      }
       /deep/ .el-table th {
        padding: 12px 0;
      }
      /deep/ .el-table::before, /deep/ .el-table__fixed::before {
        background: none;
      }
      /deep/ .el-input__inner {
        height: 32px;
        line-height: 32px;
      }
      /deep/ .el-input__icon {
        line-height: 32px;
      }
    }
    .page-box {
      height: 6%;
      padding-top: 0.10rem;
      font-size: 0.16rem;
    }
  }
  .right {
    text-align: right;
    // margin: 20px 0;
  }
/deep/ .el-table .cell.el-tooltip {
  line-height: 33px;
}
</style>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值