element表格二次封装,封装完了代码嗖嗖的少了很多

89 阅读2分钟

最近自己基于element-ui的el-table二次封装了一个表格,直接分享代码吧

<template>
  <div>
    <el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange">
      <template>
        <el-table-column v-if="selection ==='multiple'" type="selection" width="55" align="center">
        </el-table-column>
        <el-table-column v-for="(item, index) in tableHeader"
                         :key="index"
                         :prop="item.prop"
                         :label="item.label"
                         :align="item.align">
          <template v-if="item.slot" v-slot:default="scope">
            <slot :name="item.prop" :row="scope.row" :index="scope.$index"></slot>
          </template>
          <template v-else v-slot:default="scope">
              <div v-if="item.format">
                 {{item.format(scope.row)}}
              </div>
              <div v-else>
                {{scope.row[item.prop]}}
              </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" v-if='operate'>
          <template v-slot:default="scope">
            <slot name="operate" :row="scope.row" :index="scope.$index"></slot>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <el-pagination
      v-if="hasPageNation"
      :current-page.sync="pageNum"
      :page-size.sync="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :page-sizes="[10, 20, 30, 40]"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>
<script>
  export default{
    name: 'ftable',
    props: {
      // 受否可以选择
      selection: {
        type: String,
        default: 'multiple'
      },
      // 表头列
      tableHeader: {
        type: Array,
        default: () => {
          return []
        }
      },
      // 是否有操作列
      operate: {
        type: Boolean,
        default: true
      },
      // 是否分页
      hasPageNation: {
        type: Boolean,
        default: true
      },
      // 是否自动请求
      isAutoRequest: {
        type: Boolean,
        default: true
      },
      // 获取表格数据的函数
      data: {
        type: Function,
        require: true
      }
    },
    data() {
      return {
        loading: false, // 表格请求数据蒙层loading
        tableData: [], // 表格数据
        pageSize: 10, // 分页每页条数
        pageNum: 1,  // 分页当前页
        total: 0, // 总页数
        refreshParameter: {}  // 刷新表格的请求参数
      }
    },
    mounted() {
      this.isAutoRequest && this.loadData(); // 首次是否加载表格数据
    },
    methods: {
      // 勾选数据
      handleSelectionChange(data) {
        console.log(data);
      },
      // 加载数据方法
      loadData() {
        debugger
        if(this.loading) {
          return
        }
        this.loading = true;
        const parameter = this.hasPageNation ? {...this.refreshParameter, pageNum: this.pageNum, pageSize: this.pageSize} : this.refreshParameter;
        const result = this.data(parameter); // 调用父组件传过来的函数
        console.log(result); // 一个promise对象
        this.refreshParameter = {};
        if((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function')  {
          return result.then(
            res => {
              this.loading = false;
              const {list, pageNum, pageSize, total} = res;
              this.tableData = list || [];
              this.hasPageNation && pageNum &&(this.pageNum = pageNum);
              this.hasPageNation && pageSize &&(this.pageSize = pageSize);
              this.hasPageNation && total !== undefined &&(this.total = total);
            }
          ).finally(() => {
            this.loading = false;
          })
          .catch(err => {
            this.loading = false;
          })
        }
      },
      // 表格重新加载方法  param  false加载第一个 true加载当前页  object重新携带参数
      refresh(param = false) {
        const type = typeof param;
        if(type === 'boolean') {
          !param && (this.pageNum = 1);
        } else if(type === 'object') {
          this.refreshParameter = param;
        }
        this.loadData();
      },
      // 分页每页多少条
      handleSizeChange(val) {
        if (this.pageNum * val > this.total) {
          this.pageNum = 1;
        }
        this.pageNum = val;
        this.refresh();
      },
      // 分页跳到第几页
      handleCurrentChange(val) {
        this.pageNum = val;
        this.refresh(true);
      }
    }
  }
</script>

使用例子:

<ftable ref="ftable" :data="loadData" :tableHeader="tableHeader">
  <template v-slot:ipaddr="scope">
    <span style="color: red;">{{scope.row.ipaddr}}</span>
  </template>
  <template v-slot:loginLocation="scope">
    <span style="color: green;">{{scope.row.loginLocation}}</span>
  </template>
  <template v-slot:operate="scope">
    <el-button type="text">编辑</el-button>
  </template>
</ftable>
<script>
import Ftable from "@/views/components/myComponents/table"
import { list } from "@/api/monitor/logininfor";
export default {
  name: "index",
  components: {Ftable},
  dicts: ['sys_common_status'],
  data() {
    return{
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        ipaddr: undefined,
        userName: undefined,
        status: undefined
      },
      dateRange: [],
      // 表头列
      tableHeader: [
        {prop: 'infoId', label: '访问编号', align: 'center'},
        {prop: 'userName', label: '用户名称', align: 'center'},
        {prop: 'ipaddr', label: '登录地址', align: 'center', slot: true},
        {prop: 'loginLocation', label: '登录地点', align: 'center',slot: true},
        {prop: 'browser', label: '浏览完', align: 'center'},
        {prop: 'os', label: '操作系统', align: 'center'},
        {prop: 'status', label: '登录状态', align: 'center',
          format: (row) => {
            let statusShow = row.status === '0' ?  '在线' : '离线';
            return statusShow;
          }
        }
      ]
    }
  },
  methods: {
    loadData(parameter) {
      console.log(parameter);
      let data = {
        ...this.queryParams,
        dateRange: this.dateRange,
        pageSize: parameter.pageSize,
        pageNum: parameter.pageNum
      }
      console.log(data);
      return list(data).then(res => {
        console.log(res);
        return {
          list: res.rows || [],
          pageNum: data.pageNum,
          pageSize: data.pageSize,
          total: res.total
        }
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.$refs.ftable.refresh(); // 请求第一页
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
    },
  }
}
</script>

最终效果:

1700309323235.png