fix: 更新搜索栏展示问题,以及销售订单的一些问题。
This commit is contained in:
@@ -21,6 +21,11 @@ const props = defineProps({
|
||||
});
|
||||
const emit = defineEmits<Emits>();
|
||||
const tableMainRef = ref<InstanceType<typeof TableMain> | null>(null);
|
||||
const tableHeaderEl = ref<HTMLElement | null>(null);
|
||||
const tableMainHostEl = ref<HTMLElement | null>(null);
|
||||
const headerBaseHeight = ref(0);
|
||||
const headerExtraOffset = ref(0);
|
||||
const tableMainHeight = ref(0);
|
||||
const page = ref(1);
|
||||
const pageSize = ref(30);
|
||||
const total = ref(0);
|
||||
@@ -62,6 +67,15 @@ const handleExpandChange = (row: any, expandedRows: any[]) => {
|
||||
emit("expand-change", row, expandedRows);
|
||||
};
|
||||
|
||||
const recomputeTableHeight = () => {
|
||||
if (!tableMainHostEl.value) return;
|
||||
const top = tableMainHostEl.value.getBoundingClientRect().top;
|
||||
// 预留一点底部空隙,避免贴边导致分页视觉上“出屏”
|
||||
const paddingBottom = 12;
|
||||
const h = Math.floor(window.innerHeight - top - paddingBottom);
|
||||
tableMainHeight.value = Math.max(240, h);
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
reload: loadData,
|
||||
tableMainRef,
|
||||
@@ -73,31 +87,59 @@ defineExpose({
|
||||
},
|
||||
});
|
||||
|
||||
onMounted(loadData);
|
||||
onMounted(async () => {
|
||||
await loadData();
|
||||
|
||||
await nextTick();
|
||||
if (tableHeaderEl.value) {
|
||||
headerBaseHeight.value = tableHeaderEl.value.getBoundingClientRect().height;
|
||||
}
|
||||
recomputeTableHeight();
|
||||
|
||||
if (tableHeaderEl.value && "ResizeObserver" in window) {
|
||||
const ro = new ResizeObserver(entries => {
|
||||
const h = entries[0]?.contentRect?.height ?? 0;
|
||||
headerExtraOffset.value = Math.max(0, Math.round(h - headerBaseHeight.value));
|
||||
// 表头换行会影响 TableMain 的 top,需要同步重算可用高度
|
||||
requestAnimationFrame(recomputeTableHeight);
|
||||
});
|
||||
ro.observe(tableHeaderEl.value);
|
||||
onBeforeUnmount(() => ro.disconnect());
|
||||
}
|
||||
|
||||
window.addEventListener("resize", recomputeTableHeight);
|
||||
onBeforeUnmount(() => window.removeEventListener("resize", recomputeTableHeight));
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<TableHeader
|
||||
v-if="searchers !== undefined"
|
||||
: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>
|
||||
<div ref="tableHeaderEl">
|
||||
<TableHeader
|
||||
v-if="searchers !== undefined"
|
||||
:searchers="searchers"
|
||||
:tool-buttons="toolButtons"
|
||||
v-model:searcher-params="searcherParams"
|
||||
:search-click="searchClick"
|
||||
>
|
||||
<template #tool-button><slot name="tool-button"></slot></template>
|
||||
</TableHeader>
|
||||
</div>
|
||||
<div ref="tableMainHostEl">
|
||||
<TableMain
|
||||
ref="tableMainRef"
|
||||
:data="tableData"
|
||||
:total="total"
|
||||
:update-page="updatePage"
|
||||
:container-height="tableMainHeight"
|
||||
:extra-offset="headerExtraOffset"
|
||||
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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -15,16 +15,19 @@ const searcherParams = defineModel<Record<string, string>>("searcherParams");
|
||||
</script>
|
||||
<template>
|
||||
<div class="table-header">
|
||||
<SearchBar
|
||||
:searchers="searchers"
|
||||
:search-click="searchClick"
|
||||
v-model:searcher-params="searcherParams"
|
||||
:reset-click="resetClick"
|
||||
/>
|
||||
<!-- <TableToolBar class="table-tool-bar" :tool-buttons="toolButtons" /> -->
|
||||
<div>
|
||||
<slot name="tool-button"></slot>
|
||||
<div class="table-header__search">
|
||||
<SearchBar
|
||||
:searchers="searchers"
|
||||
:search-click="searchClick"
|
||||
v-model:searcher-params="searcherParams"
|
||||
:reset-click="resetClick"
|
||||
>
|
||||
<template #after-actions>
|
||||
<slot name="tool-button"></slot>
|
||||
</template>
|
||||
</SearchBar>
|
||||
</div>
|
||||
<!-- <TableToolBar class="table-tool-bar" :tool-buttons="toolButtons" /> -->
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
@@ -32,9 +35,15 @@ const searcherParams = defineModel<Record<string, string>>("searcherParams");
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.table-header__search {
|
||||
flex: 1 1 auto;
|
||||
min-width: 260px;
|
||||
}
|
||||
|
||||
.table-tool-bar {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,16 @@ defineProps({
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
// 由父组件按实际视口计算的可用高度(px)。传了则优先生效。
|
||||
containerHeight: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 表头等区域换行导致高度变化时的额外偏移量(px)
|
||||
extraOffset: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 新增:透传给 el-table 的展开行 key 列表
|
||||
expandRowKeys: {
|
||||
type: Array as PropType<(string | number)[]>,
|
||||
@@ -49,7 +59,15 @@ defineExpose({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: calc(100vh - 157px); overflow: hidden">
|
||||
<div
|
||||
:style="{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height:
|
||||
containerHeight && containerHeight > 0 ? `${containerHeight}px` : `calc(100vh - ${157 + (extraOffset || 0)}px)`,
|
||||
overflow: 'hidden',
|
||||
}"
|
||||
>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
|
||||
@@ -41,6 +41,7 @@ function reset() {
|
||||
<el-date-picker
|
||||
v-model="searcherParams[searcher.name]"
|
||||
v-if="searcher.type === 'date-range-pick'"
|
||||
class="searcher"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
:start-placeholder="$t('_prop.common.startdate')"
|
||||
@@ -48,24 +49,43 @@ function reset() {
|
||||
value-format="YYYY-MM-DD"
|
||||
></el-date-picker>
|
||||
</div>
|
||||
<el-button v-if="searchClick !== undefined" :icon="Search" type="primary" @click="searchButtonClick">
|
||||
{{ $t("_button.search") }}
|
||||
</el-button>
|
||||
<el-button v-if="searchClick !== undefined" :icon="Refresh" @click="reset">{{ $t("_button.reset") }}</el-button>
|
||||
<div class="search-actions" v-if="searchClick !== undefined">
|
||||
<el-button :icon="Search" type="primary" @click="searchButtonClick">
|
||||
{{ $t("_button.search") }}
|
||||
</el-button>
|
||||
<el-button :icon="Refresh" @click="reset">{{ $t("_button.reset") }}</el-button>
|
||||
<slot name="after-actions"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.search-bar {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
align-items: flex-start;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.searcher-box {
|
||||
padding-right: 5px;
|
||||
padding-left: 5px;
|
||||
box-sizing: border-box;
|
||||
flex: 0 1 400px;
|
||||
min-width: 240px;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.searcher {
|
||||
width: 400px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-actions {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
padding-left: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user