177 lines
4.8 KiB
Vue
177 lines
4.8 KiB
Vue
<script lang="ts" setup>
|
|
import { OperatorEnum } from "@/types";
|
|
import { PageData, PageParams } from "@/types/Basics";
|
|
import Utils from "@/utils";
|
|
import { Message } from "view-ui-plus";
|
|
import SvgIcon from "@/components/SvgIcon.vue";
|
|
import { ref, onBeforeMount, onMounted, nextTick } from "vue";
|
|
interface ReplaceParams {
|
|
page: string;
|
|
count: string;
|
|
}
|
|
interface ReplaceResult {
|
|
list: string;
|
|
total: string;
|
|
}
|
|
/* 表格插件参数类型 */
|
|
interface TablePageProps {
|
|
dataApi: (params: PageParams) => Promise<any>;
|
|
columns: object[];
|
|
tableHeight?: number;
|
|
pageParams: PageParams | undefined;
|
|
dataFilter?: ((resp: object) => object[]) | undefined;
|
|
autoLoad?: boolean | undefined;
|
|
pageType?: "small" | "default";
|
|
replaceParams?: ReplaceParams; //替换传入参数
|
|
replaceResult?: ReplaceResult; //替换返回结果
|
|
}
|
|
|
|
const props = withDefaults(defineProps<TablePageProps>(), {
|
|
autoLoad: true,
|
|
pageType: "default",
|
|
});
|
|
const tableRef = ref();
|
|
const list = ref<any[]>([]),
|
|
selectList = ref<number[]>([]),
|
|
total = ref(0),
|
|
tableH = ref(0),
|
|
tableLoading = ref(false);
|
|
const params = ref<PageParams>({ page: 1, count: 10 });
|
|
onBeforeMount(async () => {
|
|
if (props.tableHeight) tableH.value = props.tableHeight;
|
|
else tableH.value = Utils.useTableHeight();
|
|
if (!!props.pageParams) params.value = props.pageParams;
|
|
if (props.autoLoad) await getData();
|
|
});
|
|
|
|
onMounted(() => {
|
|
window.onresize = _.debounce(() => {
|
|
tableH.value = Utils.useTableHeight();
|
|
}, 1000);
|
|
});
|
|
|
|
const getData = async () => {
|
|
tableLoading.value = true;
|
|
try {
|
|
let tempParams: any = _.cloneDeep(params.value);
|
|
if (!!props.replaceParams) {
|
|
const { page, count } = props.replaceParams;
|
|
tempParams = Utils.replaceField(tempParams, [
|
|
{ n: page, o: "page" },
|
|
{ n: count, o: "count" },
|
|
]);
|
|
}
|
|
var data = await props.dataApi(tempParams);
|
|
|
|
if (!!props.replaceResult) {
|
|
const { total, list } = props.replaceResult;
|
|
data = Utils.replaceField(data, [
|
|
{ n: "total", o: total },
|
|
{ n: "list", o: list },
|
|
]);
|
|
}
|
|
// console.log(data);
|
|
|
|
total.value = data.total;
|
|
if (typeof props.dataFilter != "undefined") list.value = props.dataFilter(data);
|
|
else list.value = data.list;
|
|
|
|
await nextTick();
|
|
// setTimeout(() => {
|
|
// console.log(tableRef.value.target);
|
|
// }, 1000);
|
|
//ivu-table-tbody
|
|
} catch (error) {
|
|
console.log(error);
|
|
Message.error(error);
|
|
} finally {
|
|
tableLoading.value = false;
|
|
}
|
|
};
|
|
|
|
function selectChange(selection: any) {
|
|
selectList.value = selection;
|
|
}
|
|
async function pageUpdate(page: number) {
|
|
params.value.page = page;
|
|
await getData();
|
|
}
|
|
async function pageSizeUpdate(size: number) {
|
|
params.value.page = 1;
|
|
params.value.count = size;
|
|
await getData();
|
|
}
|
|
|
|
/** 刷新数据-更新删除用 */
|
|
// "add" | "del" | "edit" | "sel"
|
|
async function refreshData() {
|
|
params.value.page = 1;
|
|
await getData();
|
|
}
|
|
|
|
/** 重置数据 */
|
|
// "add" | "del" | "edit" | "sel"
|
|
async function reloadData(type: OperatorEnum = OperatorEnum.sel) {
|
|
let { page, count } = params.value;
|
|
if (type == OperatorEnum.add) {
|
|
if (page * count == total.value) page += 1;
|
|
} else if (type == OperatorEnum.del) {
|
|
if ((page - 1) * count + 1 == total.value) page -= 1;
|
|
} else if (type == OperatorEnum.edit) {
|
|
//page=page
|
|
} else if (type == OperatorEnum.sel) page = 1;
|
|
params.value.page = page;
|
|
await getData();
|
|
}
|
|
|
|
defineExpose({
|
|
list,
|
|
refreshData,
|
|
reloadData,
|
|
});
|
|
</script>
|
|
<template>
|
|
<Table
|
|
:columns="columns"
|
|
:height="tableHeight"
|
|
:data="list"
|
|
ref="tableRef"
|
|
@on-selection-change="selectChange"
|
|
class="link-table"
|
|
:loading="tableLoading"
|
|
no-data-text="暂无数据"
|
|
>
|
|
<template #loading>
|
|
<SvgIcon name="loading" size="50" color="6280eb" />
|
|
<div class="table-spin-load">加载中</div>
|
|
</template>
|
|
</Table>
|
|
<div class="fix mt-10">
|
|
<Page
|
|
:size="pageType"
|
|
class="fr"
|
|
:total="total"
|
|
:model-value="params.page"
|
|
:page-size="params.count"
|
|
:page-size-opts="[10, 20, 30, 40]"
|
|
@on-page-size-change="pageSizeUpdate"
|
|
@on-change="pageUpdate"
|
|
show-total
|
|
:show-sizer="pageType == 'default'"
|
|
></Page>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
::v-deep .ivu-table::before {
|
|
content: none;
|
|
}
|
|
|
|
::v-deep .ivu-table-header thead tr th {
|
|
padding: 5px 0;
|
|
}
|
|
::v-deep .table-spin-load {
|
|
color: #577afb;
|
|
}
|
|
</style>
|