102 lines
3.0 KiB
Vue
102 lines
3.0 KiB
Vue
<script lang="ts" setup>
|
|
import TableHeader from "./TableHeader.vue";
|
|
import TableMain from "./TableMain.vue";
|
|
import type { SearcherProp } from "../search-bar/SearchBarType";
|
|
import type { ToolButtonProp } from "../table-tool-bar/TableToolBarType";
|
|
import type { PropType } from "vue";
|
|
import { get } from "@/common/http/request";
|
|
interface Emits {
|
|
(e: "data-loaded", data: any[]): void;
|
|
(e: "expand-change", row: any, expandedRows: any[]): void;
|
|
}
|
|
|
|
const props = defineProps({
|
|
searchers: Array as PropType<SearcherProp[]>,
|
|
toolButtons: Array as PropType<ToolButtonProp[]>,
|
|
data: Array,
|
|
url: String,
|
|
parse: Function,
|
|
expandRowKeys: Array as PropType<(string | number)[]>,
|
|
rowKey: { type: String, default: "id" },
|
|
});
|
|
const emit = defineEmits<Emits>();
|
|
const tableMainRef = ref<InstanceType<typeof TableMain> | null>(null);
|
|
const page = ref(1);
|
|
const pageSize = ref(30);
|
|
const total = ref(0);
|
|
const searcherParams = ref({});
|
|
const tableData = ref<any[]>([]);
|
|
const updatePage = () => loadData();
|
|
const searchClick = () => loadData();
|
|
|
|
const loadData = async () => {
|
|
if (props.data !== undefined) {
|
|
total.value = props.data.length;
|
|
tableData.value = props.data.slice(
|
|
(page.value - 1) * pageSize.value,
|
|
Math.min(page.value * pageSize.value, props.data.length)
|
|
);
|
|
onDataLoaded(tableData.value);
|
|
}
|
|
if (props.url !== undefined) {
|
|
const params = new URLSearchParams();
|
|
for (const [key, value] of Object.entries(searcherParams.value)) {
|
|
params.append(key, String(value));
|
|
}
|
|
params.append("page", page.value.toString());
|
|
params.append("pageSize", pageSize.value.toString());
|
|
const urlRawData = await get(props.url, params).then(res => res.data);
|
|
const urlData = props.parse === undefined ? urlRawData : props.parse(urlRawData);
|
|
total.value = urlData.total;
|
|
tableData.value = urlData.records;
|
|
onDataLoaded(tableData.value);
|
|
}
|
|
};
|
|
|
|
// 数据处理完成后的回调
|
|
const onDataLoaded = (data: any[]) => {
|
|
emit("data-loaded", data);
|
|
};
|
|
|
|
const handleExpandChange = (row: any, expandedRows: any[]) => {
|
|
emit("expand-change", row, expandedRows);
|
|
};
|
|
|
|
defineExpose({
|
|
reload: loadData,
|
|
tableMainRef,
|
|
toggleRowExpansion: (row: any, expanded?: boolean) => {
|
|
tableMainRef.value?.toggleRowExpansion(row, expanded);
|
|
},
|
|
sort: (field: string, order: string) => {
|
|
console.log(tableMainRef.value?.tableRef);
|
|
tableMainRef.value?.tableRef?.sort(field, order);
|
|
},
|
|
});
|
|
|
|
onMounted(loadData);
|
|
</script>
|
|
<template>
|
|
<TableHeader
|
|
:searchers="searchers"
|
|
:tool-buttons="toolButtons"
|
|
v-model:searcher-params="searcherParams"
|
|
:search-click="searchClick"
|
|
>
|
|
<template #tool-button><slot name="tool-button"></slot></template>
|
|
</TableHeader>
|
|
<TableMain
|
|
ref="tableMainRef"
|
|
:data="tableData"
|
|
:total="total"
|
|
:update-page="updatePage"
|
|
v-model:page="page"
|
|
v-model:page-size="pageSize"
|
|
:expand-row-keys="expandRowKeys"
|
|
:row-key="rowKey"
|
|
@expand-change="handleExpandChange"
|
|
>
|
|
<template #columns><slot name="columns"></slot></template>
|
|
</TableMain>
|
|
</template>
|