赞
踩
应用场景:在编写后台管理系统时,常常会用到表格和翻页器,每次都需要重复的写很麻烦,并且普通表格只需要渲染对应的prop就可以了,完全可以用一个v-for判断去解决,因此一个自带翻页器的table组件就应运而生了
实现功能:
- 在渲染表格时,只需要传递列表配置即可无脑渲染,无需疯狂cv然后改一些鸡毛蒜皮的小东西
- 根据字段判断是否自定义插槽,使用具名插槽去单独编译
- 分页器和翻页的方法都绑定到同一个方法,父组件接收一个渲染列表的方法即可
- 有JSX和template两种写法,各取所需(vue2版本)
<template> <div class="hc-table"> <el-table ref="filterTable" :row-class-name="tableRowClassName" v-loading="loading" :data="tableData" :cell-style="cellStyle" @sort-change="sortChange" > <template v-for="(item, index) in columns"> <!-- solt 自定义列--> <!-- 自定义列的使用方法: 在使用插槽时#后跟slotType <template #createTime="scope"> <span>{{ parseTime(scope.row.createTime) }}</span> </template> --> <template v-if="item.type === 'slot'"> <el-table-column :class-name="item.class" :key="index" :width="item.width" :prop="item.prop" :label="item.label" :align="item.align ? item.align : 'center'" > <template slot-scope="scope"> <slot :name="item.slotType" :row="scope.row"/> </template> </el-table-column> </template> <!--普通表格--> <template v-else> <el-table-column :show-overflow-tooltip="item.showOverflowTooltip||true" v-if="item.visible !== false" :key="index" :sortable="item.sortable" :prop="item.prop" :label="item.label" :align="item.align ? item.align : 'center'" :width="item.width" ></el-table-column> </template> </template> </el-table> <div class="pagination-container" v-if="showPagination"> <el-pagination :background="background" :current-page.sync="currentPage" :page-size.sync="pageSize" :layout="layout" :page-sizes="pageSizes" :pager-count="pagerCount" :total="total" v-bind="$attrs" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> </div> </template>
<script> import { scrollTo } from '@/utils/scroll-to' export default { name: 'HcTable', props: { // 表单数据 tableData: Array, // 数据列表配置 columns: Array, // 行样式 tableRowClassName: Function, // 加载状态 loading: Boolean, // 单元格的 style 的回调方法 cellStyle: Function, // 是否展示翻页组件 showPagination: { type: Boolean, default: true }, // 总数 total: Number, // pagination的page page: Number, // pagination的limit limit: Number, pageSizes: { type: Array, default() { return [10, 20, 30, 50] } }, // 移动端页码按钮的数量端默认值5 pagerCount: { type: Number, default: document.body.clientWidth < 992 ? 5 : 7 }, 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 } }, computed: { currentPage: { get() { return this.page }, set(val) { this.$emit('update:page', val) } }, pageSize: { get() { return this.limit }, set(val) { this.$emit('update:limit', val) } } }, methods: { sortChange(filters) { this.$emit('sortChange', filters) }, handleSizeChange(val) { if (this.currentPage * val > this.total) { this.currentPage = 1 } this.$emit('pagination', { page: this.currentPage, limit: val }) }, handleCurrentChange(val) { this.$emit('pagination', { page: val, limit: this.pageSize }) } } } </script>
<style scoped>
.pagination-container {
background: #fff;
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
</style>
<script> export default { name: 'HcTable', props: { // 表单数据 tableData: Array, // 数据列表配置 columns: Array, // 行样式 tableRowClassName: Function, // 加载状态 loading: Boolean, // 单元格的 style 的回调方法 cellStyle: Function, // 是否展示翻页组件 showPagination: { type: Boolean, default: true }, // 总数 total: Number, // pagination的page page: Number, // pagination的limit limit: Number, pageSizes: { type: Array, default() { return [10, 20, 30, 50] } }, // 移动端页码按钮的数量端默认值5 pagerCount: { type: Number, default: document.body.clientWidth < 992 ? 5 : 7 }, 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 } }, computed: { currentPage: { get() { return this.page }, set(val) { this.$emit('update:page', val) } }, pageSize: { get() { return this.limit }, set(val) { this.$emit('update:limit', val) } } }, methods: { sortChange(filters) { this.$emit('sortChange', filters) }, handleSizeChange(val) { if (this.currentPage * val > this.total) { this.currentPage = 1 } this.$emit('pagination', { page: this.currentPage, limit: val }) }, handleCurrentChange(val) { this.$emit('pagination', { page: val, limit: this.pageSize }) }, renderTable() { const { tableRowClassName, loading, tableData, cellStyle, sortChange } = this return <el-table ref="filterTable" row-class-name={tableRowClassName} v-loading={loading} data={tableData} cell-style={cellStyle} on-sort-change={sortChange} > {this.columns.map((item, index) => this.renderTableColumn(item, index))} </el-table> }, renderTableColumn(item, index) { if (item.visible === false) return if (item.type === 'slot') { /* solt 自定义列 自定义列的使用方法: 在使用插槽时#后跟slotType */ return <el-table-column class-name={item.class} key={index} width={item.width} prop={item.prop} label={item.label} align={item.align ? item.align : 'center'} formatter={(row) => { return this.$scopedSlots[item.slotType]({ row: row }) }} > </el-table-column> } else { // 普通表格 return <el-table-column show-overflow-tooltip={item.showOverflowTooltip || true} key={index} sortable={item.sortable} prop={item.prop} label={item.label} align={item.align ? item.align : 'center'} width={item.width} ></el-table-column> } }, renderPagination() { const { showPagination, pageSizes, pagerCount, total, layout, currentPage, pageSize, handleSizeChange, handleCurrentChange, background } = this const listeners = { // 关键代码 - 1 'update:current-page': val => { this.currentPage = val }, 'update:limit': val => { this.pageSize = val } } if (showPagination && total > 0) { return <div class="pagination-container"> <el-pagination background={background} current-page={currentPage} page-size={pageSize} layout={layout} page-sizes={pageSizes} pager-count={pagerCount} total={total} {...{ on: listeners }} on-size-change={handleSizeChange} on-current-change={handleCurrentChange} /> </div> } } }, render(createElement, context) { return <div class="hc-table">{this.renderTable()}{this.renderPagination()}</div> } } </script>
<style scoped>
.pagination-container {
background: #fff;
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
</style>
示例:
<hc-table :loading="loading" :tableData="userList" :columns="columns" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" > <template #statusStr="scope"> {{ scope.row.status == 0 ? '正常' :'停用' }} </template> <template #operate="scope"> <el-button size="mini" type="text" @click="handleUpdate(scope.row,'reset')" >重置密码 </el-button> <el-button size="mini" type="text" @click="handleUpdate(scope.row,'edit')" >修改 </el-button> <el-button size="mini" type="text" class="color_red" @click="handleDelete(scope.row)" >删除 </el-button> </template> </hc-table>
// data中的columns列信息配置如下
columns: [
{ prop: 'userId', label: `序号` },
{ prop: 'userName', label: `账户名称` },
{ label: `状态`,type: 'slot',slotType:'statusStr' },
{
class: 'small-padding fixed-width',
width: '160',
label: `操作`,
type: 'slot',
slotType: 'operate'
}
],
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。