基于el-table表格与el-pagination分页二次封装

#el-table封装

<template>
  <div>
    <el-table
      class="customer"
      border
      size="mini"
      :data="tableData"
      @selection-change="handleSelectionChange"
      ref="Dynamic-Table"
      style="width: 100%"
    >
      <!-- <el-table-column label="序号" align="center" type="index" /> -->
      <!-- 循环表头数据,判断列显示类型 -->
      <template v-for="(col, index) in tableHeader">
        <!-- 索引行 -->
        <el-table-column
          v-if="col.type == 'index'"
          :label="col.label"
          :key="index"
          :type="col.type"
          :width="col.width"
          :align="col.align"
          :fixed="col.fixed"
        />
        <!-- 自定义表头 -->
        <el-table-column
          :key="index"
          v-else-if="col.type == 'header'"
          :width="col.width"
          :align="col.align"
        >
          <template slot="header">
            <el-input
              v-model="col.prop"
              size="mini"
              placeholder="输入列"
              class="input_text_center"
            />
          </template>
          <template slot-scope="scope">
            <slot :row="scope.row" :col="col"></slot>
          </template>
        </el-table-column>
        <!-- 多选框 -->
        <el-table-column
          v-else-if="col.type == 'selection'"
          :key="index"
          :type="col.type"
          :width="col.width"
          :align="col.align"
          :fixed="col.fixed"
        ></el-table-column>
        <!-- 输入框 -->
        <el-table-column
          v-else-if="col.type == 'input'"
          :key="index"
          :label="col.label"
          :width="col.width"
          :align="col.align"
          :prop="col.prop"
        >
          <template slot-scope="scope">
            <el-input v-model="scope.row[col.prop]" class="input_text_center" />
          </template>
        </el-table-column>
        <!-- 图片 -->
        <el-table-column
          v-else-if="col.type == 'image'"
          :key="index"
          :label="col.label"
          :width="col.width"
          :prop="col.prop"
        >
          <template slot-scope="scope">
            <div class="content-image"><img :src="scope.row[col.prop]" /></div>
          </template>
        </el-table-column>
        <!-- 给日期行加个好看的icon,属于自定义,所以要单独抽离出来 -->
        <el-table-column
          v-else-if="col.type == 'date'"
          :key="index"
          :label="col.label"
          :width="col.width"
          :min-prop="col.prop"
        >
          <template slot-scope="scope">
            <i class="el-icon-time"></i>
            <span style="margin-left: 10px">{{ scope.row[col.prop] }}</span>
          </template>
        </el-table-column>
        <!-- 操作按钮,我们不知道表格操作按钮业务需求是什么样子的,那我们就给插槽,不同业务可以按需求添加操作按钮 -->
        <el-table-column
          v-else-if="col.type == 'handle'"
          :key="index"
          :label="col.label"
          :min-width="col.width"
          :align="col.align"
          :fixed="col.fixed"
        >
          <template slot-scope="scope">
            <slot :name="col.name" :row="scope.row" :col="col"></slot>
          </template>
        </el-table-column>
        <!-- 自由项 -->
        <slot v-else-if="$scopedSlots[col.name]" :name="col.name" :column="col"></slot>
        <!-- 对于其他没有类型的列,统统算作普通默认类型。直接按照表格属性呈现就行 -->
        <el-table-column
          v-else
          :label="col.label"
          :key="index"
          :min-width="col.width"
          :prop="col.prop"
          :align="col.align"
          :fixed="col.fixed"
        ></el-table-column>
      </template>
    </el-table>
    <Pagination
      class="mt10"
      v-if="config !== undefined && config.total > 0"
      :total="config.total"
      v-on="$listeners"
      :page.sync="config.searchList.page"
      :entry.sync="config.searchList.pageSize"
      :pageSizes.sync="config.searchList.pageSizes"
    />
  </div>
</template>

<script>
// type:{
// 	selection: checkbox选项,
// 	date: 日期格式,
// 	button: 操作按钮,
// 	image: 图片,
//  index: 索引,
//  expand: 列表展开,
// 	tag: 一般用于筛选类型标签,
// }
import Pagination from './Pagination';
export default {
  components: { Pagination },
  name: 'DynamicTable',
  props: {
    config: {
      type: Object,
      default: () => {},
    },
    tableHeader: {
      type: Array,
      default: () => [],
    },
    tableData: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      tRef: null,
    };
  },
  created() {
    this._initial();
  },
  methods: {
    _initial() {
      this.$nextTick(() => {
        this.tRef = this.$refs['Dynamic-Table'];
        // this._extendTableAttrs(this.tRef)
        this._extendTableMethods(this.tRef);
      });
    },
    // 继承el-table的方法
    _extendTableMethods(ref) {
      const TABLE_METHODS = [
        'selection',
        'clearSelection',
        'toggleRowSelection',
        'toggleAllSelection',
        'doLayout',
        'sort',
      ];
      const methodMap = {};
      TABLE_METHODS.forEach(method => {
        methodMap[method] = ref[method];
      });
      Object.assign(this, methodMap);
    },
    handleSelectionChange(selection) {
      this.$emit('selection-change', selection);
    },
  },
};
</script>

<style lang="scss" scoped>
::v-deep .input_text_center {
  .el-input__inner {
    text-align: center;
  }
}
</style>

#分页

<template>
  <div class="pagination">
    <el-pagination
      background
      :current-page.sync="currentPage"
      :page-size.sync="pageSize"
      :layout="layout"
      :page-sizes="pageSizes"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>
<script>
export default {
  name: 'Pagination',
  props: {
    total: {
      required: true,
      type: Number,
    }, //数据总数
    page: {
      type: Number,
      default: 1,
    }, //当前页数
    entry: {
      type: Number,
      default: 5,
    }, //每页显示条目个数
    pageSizes: {
      type: Array,
      default() {
        return [5, 10, 20, 30, 50];
      },
    }, //设置一次展示多少行数据
    layout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper',
    }, //分页的构成,例如是否添加上一页下一页,是否支持输入跳转
  },
  computed: {
    currentPage: {
      get() {
        return this.page;
      },
      set(val) {
        this.$emit('update:page', val);
      },
    }, //利用计算属性来重置普攻。让我们可以改变父组件传递过来的分页页数和条目
    pageSize: {
      get() {
        return this.entry;
      },
      set(val) {
        this.$emit('update:entry', val);
      },
    },
  },
  methods: {
    //改变分页页数和条目,通知父组件做相应的数据改变
    handleCurrentChange(val) {
      this.$emit('handleCurrentChange', { page: this.currentPage, entry: val });
    },
    handleSizeChange(val) {
      this.$emit('handleSizeChange', { page: this.pageSize, entry: val });
    },
  },
};
</script>

#使用

<DynamicTable
      v-loading="loading"  //这些可加可不加
      @handleCurrentChange="handleCurrentChange"
      @handleSizeChange="handleSizeChange"
      element-loading-text="加载中..." //这些可加可不加
      element-loading-spinner="el-icon-loading" //这些可加可不加
      :tableData="tableData"
      :tableHeader="tableHeader"
      :config="config"
    />
          
  data(){
          /**
      tableHeader: [
        {
          type: 'index',
          width: '55',
          label: '序号',
          align: 'center',
        },
        {
          prop: '',
          width: '120',
          label: '',
          align: 'center',
        },
       {
         name:"name", 
         //如有操作列必需要有name值name值自定义,使用插槽方式
         <template v-slot:name="{row,index}">
             <el-button size="mini" type="danger" >操作</el-button>
         </template>
         type:"handle",
         label:"操作"
         width: '120',
         align: 'center',
       }
      ],
          */
      return {
          tableHeader: [], //空数组是因为我们是动态渲染表头写死的话参照上面注释
          config: {
            total: 0,
            searchList: {
              pageSizes: pageSizeOptions,
              page: 1,
              pageSize: 10,
            },
          },
          tableData: [],
         }
   },
  methods:{
    handleCurrentChange(val) {
      this.config.searchList.page = val.entry;
      this.表格请求数据();
    },
    handleSizeChange(val) {
      this.config.searchList.pageSize = val.entry;
      this.表格请求数据();
    },
  }

 

posted @   bug_设计师  阅读(135)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示