index.vue
<template>
<div class="cst-list">
<el-table :data="props.tableData" style="width: 100%" stripe ref="tableRef" :row-key="rowKey" :height="props.height"
:size="props.tableSize" :border="props.border" @selection-change="handleSelectionChange" @select="handleSelect"
@select-all="handleSelect" :highlight-current-row="props.highlightCurrentRow" @current-change="choiseTableItem">
<template v-for="(item, index) in props.tHead" :key="index">
<el-table-column v-if="item.slot" :prop="item.prop" :label="item.label" :width="item.width"
:min-width="item.minWidth" :fixed="item.fixed" :type="item.type" :show-overflow-tooltip="item.tooltip"
:align="item.align" :sortable="item.sortable" :formatter="item.formatter"
:reserve-selection="item.reserveSelection">
<template #default="scope">
<slot :name="item.prop" :row="scope.row" :column="scope.column" :index="scope.$index"></slot>
</template>
</el-table-column>
<el-table-column v-else :prop="item.prop" :label="item.label" :width="item.width" :min-width="item.minWidth"
:fixed="item.fixed" :type="item.type" :show-overflow-tooltip="item.tooltip" :align="item.align"
:sortable="item.sortable" :formatter="item.formatter" :reserve-selection="item.reserveSelection"
:selectable="selectable"></el-table-column>
</template>
</el-table>
<div class="page-box" :style="align">
<el-pagination v-if="showPage" @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="props.currentPage" :page-sizes="props.pageSizes" :page-size="props.pageSize" :layout="props.layout"
:total="props.total"></el-pagination>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, ref, inject } from 'vue'
import { Props, TypeOfYourItem } from "./type";
const emit = defineEmits([
'select',
'selection-change',
'size-change',
'update:pageSize',
'update:currentPage',
'current-change',
'choiseTableItem'
])
const props: Props = defineProps({
// 斑马纹
stripe: {
type: Boolean,
default: true
},
// 纵向边框
border: {
type: Boolean,
default: false
},
// 表格大小 large / default /small
tableSize: {
type: String,
default: 'default'
},
// 表格高度
height: {
type: Number,
default: null
},
// tooltip 主题
tooltipEffect: {
type: String,
default: 'dark'
},
// 渲染表头数据
tHead: {
type: Array,
default: () => []
},
tableData: {
type: Array,
required: true
},
rowKey: {
type: Function
},
currentPage: {
type: Number,
default: 1
},
pageSizes: {
type: Array,
default: () => [10, 20, 30, 50]
},
pageSize: {
type: Number,
default: 10
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
total: {
type: Number,
default: 0
},
// 是否展示分页
isPage: {
type: Boolean,
default: true
},
// 分页位置 left | center | right
pageAlign: {
type: String,
default: 'center'
},
highlightCurrentRow: {
type: Boolean,
default: false
},
// inject 抛出方法名
provideName: {
type: String,
default: 'selectable'
},
})
const align = computed(() => {
return { 'justify-content': props.pageAlign }
})
const showPage = computed(() => {
return props.isPage && props.tableData && props.tableData.length > 0
})
const tableRef = ref()
// 表格选中事件
const handleSelectionChange = (val: any) => {
emit('selection-change', val)
}
// 表格选中
const handleSelect = (val: any, obj: any) => {
emit('select', val, obj)
}
// 每页条数改变
const handleSizeChange = (val: any) => {
emit('size-change', val)
emit('update:pageSize', val)
}
// 当前页改变
const handleCurrentChange = (val: any) => {
emit('update:currentPage', val)
emit('current-change', val)
}
const handtop = () => {
tableRef.value.toggleAllSelection() // 触发 table 表格上的全选事件
}
const selectable = inject(`${props.provideName}`, () => () => true);
defineExpose({
tableRef,
handtop,
selectable
})
const choiseTableItem = (val: any) => {
emit('choiseTableItem', val)
}
</script>
<style lang="less" scoped>
.cst-list {
.page-box {
display: flex;
margin-top: 24px;
}
}
</style>
type.ts
export type Props = {
stripe?: boolean;
border?: boolean;
tableSize?: string;
height?: number;
tooltipEffect?: string;
tHead?: any;
total: number;
isPage: boolean,
pageAlign: string,
tableData: any,
highlightCurrentRow: boolean,
currentPage: number,
pageSizes: any,
pageSize: number,
layout: string,
provideName?: string,
}
export type TypeOfYourItem = {
slot: Boolean,
prop: String,
label: String,
width: Number | String,
minWidth: Number | String,
fixed: String | Boolean,
type: String,
tooltip: Boolean,
align: String,
sortable: Boolean | String,
formatter: any,
reserveSelection: Boolean,
}
组件中使用
<template>
<el-card>
<el-input placeholder="请输入" style="width: 200px;"></el-input>
<el-input placeholder="请输入" style="width: 200px;"></el-input>
<el-input placeholder="请输入" style="width: 200px;"></el-input>
<el-input placeholder="请输入" style="width: 200px;"></el-input>
<el-button type="primary">搜索</el-button>
<el-button type="primary">重置</el-button>
</el-card>
<br />
<el-card>
<systemList
:tHead="tHead"
:tableData="tableData"
v-model:current-page="dataState.pageinfo.currPage"
v-model:page-size="dataState.pageinfo.pageSize"
v-model:isPage="isPage"
:total="dataState.pageinfo.total"
@size-change="sizeChange"
@current-change="currentChange"
>
<template #merchantStatus="{row}">
{{ row }}
</template>
<template #operate="{row}">
<el-button type="text">查看详情</el-button>
</template>
</systemList>
</el-card>
</template>
<script setup lang="ts">
import systemList from '@/components/tablePagination/index.vue'
import { reactive, ref, toRefs } from 'vue'
import { TabForm, TypeOfYourItem } from "./type";
// 不展示分页
const isPage = ref(true)
const dataState = reactive<TabForm>({
pageinfo: {
total: 0,
currPage: 1,
pageSize: 10
},
applyForm: {
merchantStatus: '',
rejectReason: ''
},
tableData: [
{
auditId: '123',
merchantId: '123',
merchantName: '123',
applyTime: '123',
merchantStatus: '123',
auditTime: '123',
operate: '123',
},
{
auditId: '123',
merchantId: '123',
merchantName: '123',
applyTime: '123',
merchantStatus: '123',
auditTime: '123',
operate: '123',
},
{
auditId: '123',
merchantId: '123',
merchantName: '123',
applyTime: '123',
merchantStatus: '123',
auditTime: '123',
operate: '123',
},
{
auditId: '123',
merchantId: '123',
merchantName: '123',
applyTime: '123',
merchantStatus: '123',
auditTime: '123',
operate: '123',
},
{
auditId: '123',
merchantId: '123',
merchantName: '123',
applyTime: '123',
merchantStatus: '123',
auditTime: '123',
operate: '123',
},
],
})
const { tableData } = toRefs(dataState)
const tHead: TypeOfYourItem[] = [
{ align: 'center', tooltip: true, prop: 'auditId', label: '申请单号', minWidth: 100, slot: false },
{ align: 'center', tooltip: true, prop: 'merchantId', label: '商户编号', minWidth: 100, slot: false },
{ align: 'center', tooltip: true, prop: 'merchantName', label: '商户名称', minWidth: 140, slot: false },
{ align: 'center', tooltip: true, prop: 'applyTime', label: '申请时间', minWidth: 200, slot: false },
{ align: 'center', tooltip: true, prop: 'merchantStatus', label: '申请单状态', minWidth: 140, slot: true },
{ align: 'center', tooltip: true, prop: 'auditTime', label: '审核时间', minWidth: 140, slot: false },
{ align: 'center', tooltip: true, prop: 'operate', label: '操作', minWidth: 140, slot: true }
]
// 当前页数改变
const currentChange = (val: number) => {
dataState.pageinfo.currPage = val
// 调用列表方法
}
const sizeChange = (val: number) => {
dataState.pageinfo.currPage = 1
dataState.pageinfo.pageSize = val
}
</script>
<style lang="less" scoped>
</style>
type.ts
export type TabForm = {
pageinfo: {
total: number;
currPage: number;
pageSize: number;
};
applyForm: {
merchantStatus: string;
rejectReason: string;
};
tableData: {
auditId: string;
merchantId: string,
merchantName: string,
applyTime: string,
merchantStatus: string,
auditTime: string,
operate: string,
}[];
}
export type TypeOfYourItem = {
slot: boolean,
prop: string,
label: string,
align: number | string,
minWidth: number | string,
tooltip: boolean
}