<template>
<div>
<a-table
class="k-table"
:columns="columns"
:data-source="origninData"
:loading="loading"
:bordered="bordered"
:pagination="false"
:size="size"
:rowKey="(record, index) => index + 1"
:row-selection="rowSelection"
:scroll="{ x: 'max-content', y: maxY }"
>
<template class="k-table-slot" v-for="(item, i) in columns" v-slot:[item.builder]="slotProps">
<KBuilder v-if="item.builder" class="builder" :name="item.builder" :row="slotProps" :column="item" />
<!-- 加下面这行才会渲染,也不知啥原因 -->
<span v-else>{{ slotProps }}</span>
</template>
</a-table>
<a-pagination
class="k-pagination"
show-quick-jumper
showSizeChanger
:pageSizeOptions="paginationData.pageSizeOptions"
:current="current"
:pageSize="paginationData.pageSize"
:total="pageTotal"
:showTotal="paginationData.showTotal"
:size="pageSizes"
@change="paginationData.onChange"
@showSizeChange="paginationData.onShowSizeChange"
/>
</div>
</template>
<script>
import KBuilder from './KBuilder'
// import { findParentComponents } from '@/utils/KUtils/getData'
/**
* @origninColumns Table表头
* @data Table表格数据
* @loading 表格懒加载
* @bordered 是否展示外边框和列边框
* @size 表格尺寸,可选值为 large、small、default 或者不填
* @rowKey 序号:使用方法在columns配置中加入 { title: "序号", customRender: (text, record, index) => index + 1 },
* @pageTotal 分页条数
* @pageSizes 分页尺寸
*/
export default {
name: 'KTable',
components: {
KBuilder
},
props: {
origninColumns: {
type: Array,
default: () => []
},
origninData: {
type: Array,
default: () => []
},
loading: {
type: Boolean,
default: false
},
bordered: {
type: Boolean,
default: true
},
size: {
type: [String, Number],
default: 'default'
},
pageTotal: {
type: Number,
default: 0
},
pageSizes: {
type: [String, Number],
default: 'default'
},
pageNo: {
type: Number,
default: 0
}
},
mounted() {
// this.PVM = findParentComponents(this, 'domcumentName')[0]
},
data() {
return {
selectedRowKeys: [], // 选中key
selectedRows: [], // 选中数组
maxY: 0,
paginationData: {
current: 1,
pageSize: 10,
showTotal: (total, range) => {
return ' 共' + total + '条'
},
pageSizeOptions: ['10', '20', '30', '50', '100'],
onChange: (pageNo, pageSize) => {
this.paginationData.current = pageNo
this.paginationData.pageSize = pageSize
this.$emit('pagination', { pageSize, pageNo })
// this.PVM.getPageData({ ...this.PVM.queryParams, pageSize, pageNo })
},
// 改变每页数量时更新显示
onShowSizeChange: (current, pageSize) => {
this.paginationData.current = 1
this.paginationData.pageSize = pageSize
this.$emit('pagination', { pageSize, pageNo: current })
// this.PVM.getPageData({ ...this.PVM.queryParams, pageSize, pageNo: current })
}
}
}
},
created() {
this.maxY = (document.documentElement.clientHeight / 100) * 55
},
methods: {
onCellClick(record) {
this.$emit('CellClick', record)
}
},
computed: {
current({ pageNo, paginationData }) {
return pageNo || paginationData.current
},
columns({ origninColumns }) {
return origninColumns?.map(item => {
return {
...item,
scopedSlots: {
customRender: item.builder
}
}
})
},
rowSelection() {
return {
selectedRowKeys: this.selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
this.$emit('onChange')
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
},
onSelect: (record, selected, selectedRows) => {
this.$emit('onSelect')
console.log(record, selected, selectedRows)
},
onSelectAll: (selected, selectedRows, changeRows) => {
this.$emit('onSelectAll')
console.log(selected, selectedRows, changeRows)
}
}
}
},
watch: {}
}
</script>
<style lang="less" scoped>
.k-table {
margin-top: 24px;
word-break: break-all !important;
}
.k-table-slot {
cursor: pointer;
}
.k-pagination {
display: flex;
margin-top: 12px;
justify-content: flex-end;
}
/deep/.ant-table-tbody tr:nth-child(2n) {
background-color: #f7f9fc !important;
}
/deep/.ant-table-column-title {
font-size: 14px;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #909399;
}
/deep/.ant-table-content {
font-size: 14px;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #303133;
}
/deep/.ant-table-tbody > tr > td {
padding: 16px 12px;
}
</style>
1.重写表头 ------- KBuilder.js
function isFunction(value) {
return typeof value === 'function'
}
function isVnode(ctx, scope) {
return scope.constructor.name == ctx.parent.$vnode.constructor.name
}
function findSlot(ctx, slotName) {
const ctxSlot = ctx.scopedSlots[slotName.toLowerCase()]
if (isFunction(ctxSlot)) {
return ctxSlot
}
let parent = ctx.parent
while (parent) {
if (isFunction(parent.$scopedSlots?.[slotName])) {
return parent.$scopedSlots[slotName]
} else {
parent = parent.$parent
}
}
return null
}
export default {
name: 'KBuilder',
functional: true,
props: {
name: {
type: [Function, String, Object],
default: ''
}
},
render: (h, ctx) => {
const scope = ctx.props.name
if (isVnode(ctx, scope)) return scope
if (isFunction(scope)) {
return scope(h, ctx.data.attrs, ctx.listeners)
}
if (scope && typeof scope === 'string') {
ctx._slot = ctx._slot || findSlot(ctx, scope)
if (ctx._slot) {
return ctx._slot(ctx.data.attrs)
}
}
return h(null)
}
}
2.目录结构
3.项目使用
<KTable
:origninColumns="[{
title: '序号',
align: 'left',
fixed: 'left',
width: 75,
key: 'index',
customRender: (text, record, index) => index + 1
},
{
title: '合同编号',
align: 'left',
dataIndex: 'contractNo',
width: 135,
sortable: false,
key: 'contractNo'
}]"
:origninData="dataSource"
:loading="loading"
:pageTotal="total"
:current="pages.pageNo"
@pagination="onPagination"
>
<template #action="{row}">
<a-icon class="action-icon" type="form" title="编辑" @click="onEdit(row)" />
<a-popconfirm title="确定删除吗?" @confirm="() => onDelet(row)">
<a-icon class="action-icon" type="delete" title="删除" />
</a-popconfirm>
</template>
</KTable>