el-table 组件(部分)

99 阅读2分钟

引言:本文章仅为个人记录 封装基本el-table 使用

父组件代码:

<template>
  <div class="app-container">
    <div class="table_wrap">
      <com-table ref="comTableRef"
                 :isLoading="isLoading"
                 :tableTitle="tableTitle"
                 :funcBtn="funcBtn"
                 :tableData="tableData"
                 @queryData="queryData"></com-table>
    </div>
  </div>
</template>

<script>

import ComTable from "xxxxxxxx/xxxxxxxx/comTable.vue"
export default {
  components: {
    ComTable,
  },
  data () {
    return {
      tableData: [],//表格数据
      funcBtn: [//表格按钮
        {
          name: "修改",
          type: "primary",
          icon: "el-icon-edit",
          clickBtn: () => {
            this.showData();
          },
        },
      ],
      tableTitle: [],//表格表头
      typeList: [],//字典值列表
      isLoading: false,//表格loading
    }
  },
  mounted () {
    this.initDict();
    this.initQuery()
  },
  methods: {
    /** 修改 */
    showData () {

    },

    initDict () {
     //可发起字典数据请求,  此处直接赋值
      this.typeList = [{ value: '1', label: '启用' }, { value: '2', label: '停用' },]

      this.tableTitle = [
        { title: "凭证代码", prop: "voucherCode" },
        { title: "凭证名称", prop: "voucherName" },
        
        //字典值需要转义时将字典数据传入表格组件
        { title: "状态", prop: "bizKeydataCode", dictList: this.typeList },
      ]
    },

    /** 查询列表 */
    initQuery () {
      this.$refs.comTableRef.currentPage = 1;
      this.queryData();
    },

    /** 列表请求 */
    async queryData () {
      this.isLoading = true;

      setTimeout(() => {

        this.tableData = [
          { voucherCode: '111', voucherName: "测试1", bizKeydataCode: "1,2", bizKeydataName: "Code2", },
          { voucherCode: '222', voucherName: "测试2", bizKeydataCode: "Code2", bizKeydataName: "Name2", },
          { voucherCode: '333', voucherName: "测试3", bizKeydataCode: "1", bizKeydataName: "2", },
          { voucherCode: '444', voucherName: "测试4", bizKeydataCode: "1,2", bizKeydataName: "2", },
          { voucherCode: '555', voucherName: "测试5", bizKeydataCode: "1", bizKeydataName: "2", }
        ];


        this.$refs.comTableRef.totalDataNum = 5;

        this.isLoading = false;
      }, 2000)
    },
  }

}
</script>

表格组件代码:


<template>
  
  <div>
    <!--表格-->
    <div class="table_wrap">
      <el-table v-loading="isLoading"
                :data="tableData"
                size="mini"
                border
                stripe
                @selection-change="handleCheckbox">

        <!-- 多选-->
        <el-table-column v-if="hasCheckbox"
                         width="60"
                         type="selection">
        </el-table-column>

        <!-- 单选 -->
        <el-table-column v-if="hasRadio"
                         width="60"
                         align="center">
          <template slot-scope="scope">
            <el-radio :label="scope.$index+1"
                      v-model="radioVal"
                      @change.native="handleRadio(scope.row)">&nbsp;</el-radio>
          </template>
        </el-table-column>

        <!-- 序号 -->
        <el-table-column type="index"
                         label="序号"
                         width="60px"
                         align="center">
          <template slot-scope="scope">{{(currentPage-1)*pageSize+scope.$index+1}}</template>
        </el-table-column>

        <!-- 列循环 -->
        <el-table-column v-for="(item,index) in tableTitle"
                         :key="index"
                         :label="item.title"
                         min-width="120px"
                         align="center"
                         show-overflow-tooltip>
          <template slot-scope="scope">

            <!-- 字典格式化 -->
            <span v-if="item.dictList && item.dictList.length>0">{{formatterDict(item,scope.row)}}</span>

            <!--字段显示 -->
            <span v-else>{{scope.row[item.prop]}}</span>

          </template>

        </el-table-column>

        <!-- 按钮 -->
        <el-table-column v-if="funcBtn && funcBtn.length > 0 "
                         fixed="right"
                         align="center"
                         label="操作"
                         :min-width="funcBtn.length > 4?160:120">
          <template slot-scope="scope">
            <span v-for="(item, index) in funcBtn"
                  :key="index">

              <el-button size="mini"
                         :type="item.type"
                         :icon="item.icon"
                         @click="backClickBtn(item,scope.row)">{{item.name}}</el-button>
            </span>
          </template>
        </el-table-column>
      </el-table>
    </div>
    
    <!--分页-->
    <div class="page-break"
         v-if="tableData.length>0">
      <el-pagination background
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange"
                     layout="total,sizes,prev,pager,next,jumper"
                     :current-page="currentPage"
                     :page-sizes="[5,10,20,30]"
                     :page-size="pageSize"
                     :total="totalDataNum"></el-pagination>
    </div>
  </div>
</template>

<script>
export default {
  props: {

    isLoading: {//表格loading
      type: Boolean,
      default: () => false,
    },

    tableData: {//表格数据
      type: Array,
      default: () => [],
    },

    tableTitle: {//表格title
      required: true,
      type: Array,
      default: () => [],
    },

    funcBtn: {//表格内按钮
      type: Array,
      default: () => [],
    },

    hasCheckbox: {//表格checkbox
      type: Boolean,
      default: () => false,
    },

    hasRadio: {//表格radio
      type: Boolean,
      default: () => false,
    },
  },

  watch: {

  },

  data () {
    return {
      radioVal: null, //单选按钮的值
      selectTableData: null, //选中的列表数据
      currentPage: 1, //当前页
      pageSize: 10, //每页显示条数
      totalDataNum: 0, //数据总条数
    };
  },

  methods: {

    /** 单选列表数据 */
    handleRadio (row) {

      this.selectTableData = row;

      console.log(' this.selectTableData', this.selectTableData);

    },

    /** 复选列表数据 */
    handleCheckbox (val) {

      this.selectTableData = val;

      console.log(' this.selectTableData', this.selectTableData);
    },

    /** 辅助回调绑定事件 */
    backClickBtn (attr, row) {
      this.selectTableData = row;
      attr.clickBtn(this.selectTableData);
    },

    /** 条变化 */
    handleSizeChange (pageSize) {
      this.pageSize = pageSize;
      this.$emit("queryData");
    },

    /** 页变化 */
    handleCurrentChange (currentPage) {
      this.currentPage = currentPage;
      this.$emit("queryData");
    },

    /** 格式化字典 */
    formatterDict (item, row) {

      if (item.dictList && item.dictList.length > 0) {

        //多个值时拼接label
        if (row[item['prop']].includes(',')) {

          const strArr = row[item['prop']].split(',')

          const labels = strArr.map(ele => {
            const obj = item.dictList.find(v => v.value === ele);
            return obj ? obj.label : null;
          })

          return labels.join(',') || '--';

        } else {

          let val = "";

          item.dictList.forEach((v) => {

            if (v.value + "" == row[item['prop']] + "") val = v.label;

          });

          return val || '--';
        }


      }
    },

  },
};
</script>

<style lang="scss" scoped>
::v-deep .el-radio__label {
  display: none;
}

.page-break {
  text-align: right;
  height: 34px;
  margin-top: 5px;
}
</style>