Files
svc-hall-front/src/components/TablePageAlova.vue
T

119 lines
3.4 KiB
Vue

<template>
<!-- 表格 -->
<Table :columns="columns" :data="list" :height="tableH" :loading="loading" no-data-text="暂无数据"
class="link-table table-bottom-box" @on-selection-change="selectChange">
<template #loading>
<div class="table-spin-load">加载中</div>
</template>
</Table>
<!-- 分页 / 插槽 -->
<div class="page-panel">
<div class="fl ml-15 align-middle">
<slot :checkList="selectList" />
</div>
<Page class="page-box fr" :total="total" :model-value="page" :page-size="pageSize"
:page-size-opts="[10, 20, 30, 40]" show-total show-sizer placement="top" @on-change="onPageChange"
@on-page-size-change="onSizeChange" />
</div>
</template>
<script setup lang="ts">
import { computed, ref, onMounted } from 'vue'
import { Message } from 'view-ui-plus'
import Utils from '@/utils'
import { OperatorEnum } from '@/types'
interface Props {
/** 必填:alova-gen 生成的 selectTextbook 方法(或任意同形方法) */
dataApi: any
columns: any[]
dataParams: any
tableHeight?: number
autoLoad?: boolean
dataFilter?: (resp: any) => any[],
formatResponse?: (res: any) => { total: number; list: any[] }
}
const props = withDefaults(defineProps<Props>(), {
autoLoad: true,
formatResponse: (res: any) => ({ total: res.total, list: res.content })
})
const emit = defineEmits<{
(e: 'selection-change', list: number[]): void
}>()
onMounted(() => {
})
/* ---------------- 表格高度 ---------------- */
const tableH = ref(props.tableHeight ?? Utils.useTableHeight())
/* ---------------- 选中行 ---------------- */
const selectList = ref<number[]>([])
function selectChange(rows: any[]) {
selectList.value = rows.map((r: any) => r.id)
emit('selection-change', selectList.value)
}
/* ---------------- 分页 + 请求 ---------------- */
const {
loading,
data: resp,
send: sendLoad,
page,
pageSize,
total,
reload
} = usePagination(
(current: number, size: number) =>
props.dataApi({
...props.dataParams, // 合并外部条件
pageIndex: current,
pageSize: size,
}),
{
// total: res => res.total,
// data: res => res.list,
total: res => props.formatResponse(res).total,
data: res => props.formatResponse(res).list,
// 默认分页参数
initialPage: 1,
initialPageSize: 10,
immediate: props.autoLoad,
watchingStates: [() => props.dataParams]
}
)
/* 列表数据 */
const list = computed(() => {
if (!resp.value) return []
return props.dataFilter ? props.dataFilter(resp.value) : resp.value
})
/* ---------------- 翻页事件 ---------------- */
const onPageChange = (p: number) => (page.value = p)
const onSizeChange = (s: number) => (pageSize.value = s)
/* ---------------- 外部可调用 ---------------- */
function refreshData() {
page.value = 1
reload()
}
function reloadData(type: OperatorEnum = OperatorEnum.sel) {
let p = page.value
const s = pageSize.value
if (type === OperatorEnum.add && p * s === total.value) p += 1
if (type === OperatorEnum.del && (p - 1) * s + 1 === total.value) p -= 1
if (p < 1) p = 1
page.value = p
sendLoad()
}
defineExpose({ list, refreshData, reloadData })
</script>
<style scoped>
/* 沿用旧样式即可 */
</style>