20260902223822
This commit is contained in:
1 parent
db7813a2d2
commit
c8940f6e03
11 files changed
+327
-922
No files matched your search
@@ -10,6 +10,8 @@ defineOptions({ inheritAttrs: false })
|
||||
const props = defineProps({
|
||||
virtual: { type: Boolean, default: true },
|
||||
virtualX: { type: Boolean, default: true },
|
||||
// 是否在非横向虚拟滚动时自动铺满容器;默认按列配置宽度展示。
|
||||
autoFitWidth: { type: Boolean, default: false },
|
||||
// 列宽拖拽默认开启;false=关闭;{ disabled: (col) => boolean }=按列禁用
|
||||
// (铺满容器的弹性列应禁用拖拽,见库文档「列宽铺满容器hack方式」)
|
||||
colResizable: { type: [Boolean, Object], default: true },
|
||||
@@ -73,7 +75,7 @@ const tableTheme = computed(() => props.theme ?? (appStore.darkMode ? 'dark' : '
|
||||
// 需从 vnode.props 探测;绑定关系在模板编写时确定,运行期不会变化,无需响应式。
|
||||
const columnsBound =
|
||||
'onUpdate:columns' in (getCurrentInstance()?.vnode.props ?? {})
|
||||
const effectiveColResizable = columnsBound ? props.colResizable : false
|
||||
const effectiveColResizable = columnsBound && !props.autoFitWidth ? props.colResizable : false
|
||||
|
||||
// Tab 面板从隐藏恢复时,等到容器拥有有效尺寸再刷新虚拟滚动布局。
|
||||
// rAF 将同一帧内的多次 ResizeObserver 通知合并,避免重复重排。
|
||||
@@ -276,6 +278,14 @@ const seqConfig = computed(() => {
|
||||
width: Number(cfg.width ?? 50),
|
||||
}
|
||||
})
|
||||
const seqWidth = ref(seqConfig.value.width)
|
||||
watch(
|
||||
() => seqConfig.value.width,
|
||||
(width) => {
|
||||
seqWidth.value = width
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
const columnDragConfig = computed(() => {
|
||||
if (!columnsBound || !props.columnDraggable) return false
|
||||
const configured = props.columnDraggable === true ? {} : props.columnDraggable
|
||||
@@ -298,16 +308,18 @@ const columnDragConfig = computed(() => {
|
||||
}
|
||||
})
|
||||
const hasRowSelection = computed(() => Boolean(props.rowSelection))
|
||||
const selectionWidth = ref(44)
|
||||
const dragRowColumn = {
|
||||
type: 'dragRow',
|
||||
dataIndex: '__drag_row__',
|
||||
title: '',
|
||||
width: 40,
|
||||
resizable: false,
|
||||
}
|
||||
const dragRowWidth = ref(dragRowColumn.width)
|
||||
|
||||
function getHeaderAlign(column) {
|
||||
if (column.headerAlign) return column.headerAlign
|
||||
if (column.type === 'seq') return 'center'
|
||||
if (isSelectionColumn(column)) return 'center'
|
||||
if (column.dataIndex === 'actions') return 'center'
|
||||
if (column.actions && column.actions.length) return 'center'
|
||||
@@ -322,14 +334,13 @@ const displayColumns = computed(() => {
|
||||
if (seq.enabled) {
|
||||
cols.unshift({
|
||||
type: 'seq',
|
||||
width: seq.width,
|
||||
width: seqWidth.value,
|
||||
dataIndex: '',
|
||||
title: seq.title,
|
||||
resizable: false,
|
||||
})
|
||||
}
|
||||
if (props.rowDraggable) cols.unshift(dragRowColumn)
|
||||
if (hasRowSelection.value) cols.unshift(selectionColumn)
|
||||
if (props.rowDraggable) cols.unshift({ ...dragRowColumn, width: dragRowWidth.value })
|
||||
if (hasRowSelection.value) cols.unshift({ ...selectionColumn, width: selectionWidth.value })
|
||||
return cols.map((column) => ({
|
||||
...column,
|
||||
headerAlign: getHeaderAlign(column),
|
||||
@@ -338,6 +349,15 @@ const displayColumns = computed(() => {
|
||||
|
||||
// 剥离内部列(选择列、序号列、拖拽列)后回传,避免污染父组件 columns
|
||||
function onColumnsUpdate(columns) {
|
||||
for (const column of columns || []) {
|
||||
if (isSelectionColumn(column) && column.width != null) {
|
||||
selectionWidth.value = Number.parseInt(column.width, 10) || selectionWidth.value
|
||||
} else if (column.type === 'seq' && column.width != null) {
|
||||
seqWidth.value = Number.parseInt(column.width, 10) || seqWidth.value
|
||||
} else if (column.type === 'dragRow' && column.width != null) {
|
||||
dragRowWidth.value = Number.parseInt(column.width, 10) || dragRowWidth.value
|
||||
}
|
||||
}
|
||||
const originalByKey = new Map(
|
||||
props.columns.map((col) => [String(col.key ?? col.dataIndex ?? ''), col]),
|
||||
)
|
||||
@@ -592,7 +612,7 @@ defineExpose({
|
||||
<div
|
||||
ref="rootRef"
|
||||
class="fms-table"
|
||||
:class="[bordered ? 'fms-table--bordered' : '']"
|
||||
:class="[bordered ? 'fms-table--bordered' : '', autoFitWidth ? 'fms-table--auto-fit-width' : '']"
|
||||
@keydown.capture="handleKeydownCapture"
|
||||
>
|
||||
<StkTable
|
||||
@@ -660,6 +680,11 @@ defineExpose({
|
||||
will-change: transform;
|
||||
}
|
||||
}
|
||||
|
||||
/* 不自适应时按列配置宽度展示;自适应模式不启用列宽拖拽,使用库默认布局。 */
|
||||
.fms-table:not(.fms-table--auto-fit-width) :deep(.stk-table-main) {
|
||||
flex: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- 非 scoped 全局样式:选择列原生 checkbox 外观模拟 antdv-next Checkbox,
|
||||
@@ -684,15 +709,6 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
|
||||
/* 列宽铺满容器(库文档「列宽铺满容器hack方式」):
|
||||
开启 col-resizable 后库默认把 .stk-table-main 设为 flex:none + fit-content,
|
||||
表格收缩到内容宽。非 virtual-x(列数 ≤ 阈值、未设宽列走原生自适应)时覆盖回
|
||||
flex:1 使表格铺满容器;配合「固定列设 width、弹性列设 minWidth 且禁用其拖拽」
|
||||
的列配置约定使用。宽表(virtual-x,横向滚动)保持库的收缩行为。 */
|
||||
.fms-table__inner.stk-table:not(.virtual-x) .stk-table-main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.fms-checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in new issue
Block a user