20260727225141

This commit is contained in:
oneao committed 2026-07-27 22:51:41 +08:00
1 parent 9dbaef7787
commit 63588bd217
97 files changed
+1309 -145

No files matched your search

@@ -200,6 +200,7 @@ const selectionColumn = createSelectionColumn({
getDataSource: () => props.dataSource,
getRowKey,
getSelectedRowKeys: () => props.rowSelection?.selectedRowKeys ?? [],
isRowDisabled: (row) => Boolean(props.rowSelection?.getCheckboxProps?.(row)?.disabled),
onChange: (keys, rows) => props.rowSelection?.onChange?.(keys, rows),
});
@@ -213,6 +214,17 @@ async function scrollToRow(rowKey) {
table.scrollTo(idx * rowHeight, null);
}
// 新增行等程序化场景使用:滚动到目标行,并让该行立即进入编辑状态。
// activeRowKey 仅控制当前行高亮,不应隐式触发编辑,因此单独暴露此方法。
async function editRow(rowKey, focusCol = null) {
await scrollToRow(rowKey);
await nextTick();
const row = props.dataSource.find((item) => String(getRowKey(item)) === String(rowKey));
if (!row) return;
tableRef.value?.setCurrentRow?.(row, { silent: true });
activateEditing(row, focusCol);
}
function getSelectedArea() {
return tableRef.value?.getSelectedArea?.();
}
@@ -388,6 +400,7 @@ onBeforeUnmount(() => {
defineExpose({
scrollToRow,
editRow,
getSelectedArea,
clearSelectedArea,
setRowExpand,
@@ -455,6 +468,11 @@ defineExpose({
line-height: 1;
margin: 0;
&.disabled {
cursor: not-allowed;
opacity: 0.45;
}
input {
position: absolute;
width: 0;
@@ -24,6 +24,12 @@ function notifyChange(ctx, editor, row, col, value) {
ctx.onChange(row, col, value);
}
function isEditorDisabled(editor, row) {
return typeof editor.disabled === "function"
? Boolean(editor.disabled(row))
: Boolean(editor.disabled);
}
function createFocusHandler(ctx, row, col, selectText = false) {
return ({ component, el }) => {
if (!ctx.shouldFocus(row, col)) return;
@@ -109,6 +115,10 @@ function createCheckbox(row, col, editor, ctx) {
? "fms-checkbox fms-cell-editor-root checked"
: "fms-checkbox fms-cell-editor-root",
onClick: stop,
// StkTable 在 mousedown 阶段处理单元格选区和行编辑。checkbox 是
// 始终可直接操作的控件,需要在该阶段隔离事件,避免第一次点击
// 只激活编辑态、第二次点击才真正切换。
onMousedown: stop,
},
[
h("input", {
@@ -127,6 +137,7 @@ function createCheckbox(row, col, editor, ctx) {
update(value);
},
onClick: stop,
onMousedown: stop,
onVnodeMounted: focus,
onVnodeUpdated: focus,
}),
@@ -138,6 +149,9 @@ function createCheckbox(row, col, editor, ctx) {
export function createEditableCell(col, ctx) {
const editor = col.editor;
return ({ row }) => {
if (isEditorDisabled(editor, row)) {
return displayValue(row, col, editor);
}
// checkbox 始终可交互,点击即切换,无需先让整行进入编辑态
if (editor?.type === "checkbox") {
return createCheckbox(row, col, editor, ctx);
@@ -15,7 +15,13 @@ const stop = (e) => e.stopPropagation();
* @param {Function} options.onChange - 选中变化回调 (keys, rows)
* @returns {Object} selectionColumn
*/
export function createSelectionColumn({ getDataSource, getRowKey, getSelectedRowKeys, onChange }) {
export function createSelectionColumn({
getDataSource,
getRowKey,
getSelectedRowKeys,
isRowDisabled = () => false,
onChange,
}) {
// 已选 key 集合,内部响应式计算,仅对外暴露 column 对象
const selectedRowKeySet = computed(() => new Set(getSelectedRowKeys()));
const rowByKey = computed(() => {
@@ -30,6 +36,7 @@ export function createSelectionColumn({ getDataSource, getRowKey, getSelectedRow
}
function changeRow(row, checked) {
if (isRowDisabled(row)) return;
const nextKeys = new Set(selectedRowKeySet.value);
const key = getRowKey(row);
if (checked) nextKeys.add(key);
@@ -40,6 +47,7 @@ export function createSelectionColumn({ getDataSource, getRowKey, getSelectedRow
function changeAll(checked) {
const nextKeys = new Set(selectedRowKeySet.value);
getDataSource().forEach((row) => {
if (isRowDisabled(row)) return;
const key = getRowKey(row);
if (checked) nextKeys.add(key);
else nextKeys.delete(key);
@@ -50,11 +58,12 @@ export function createSelectionColumn({ getDataSource, getRowKey, getSelectedRow
// 行复选框:原生 <input type="checkbox">,零组件开销
const SelectionCell = ({ row }) => {
const key = getRowKey(row);
const disabled = isRowDisabled(row);
const checked = selectedRowKeySet.value.has(key);
return h(
"label",
{
class: checked ? "fms-checkbox checked" : "fms-checkbox",
class: ["fms-checkbox", { checked, disabled }],
onClick: stop,
onMousedown: stop,
},
@@ -62,6 +71,7 @@ export function createSelectionColumn({ getDataSource, getRowKey, getSelectedRow
h("input", {
type: "checkbox",
checked,
disabled,
onChange: (e) => {
e.stopPropagation();
changeRow(row, e.target.checked);
@@ -76,7 +86,7 @@ export function createSelectionColumn({ getDataSource, getRowKey, getSelectedRow
// 表头只统计当前数据中的选中项,避免筛选后被隐藏的 key 干扰状态。
const SelectionHeaderCell = () => {
const rows = getDataSource();
const rows = getDataSource().filter((row) => !isRowDisabled(row));
let selectedCount = 0;
for (const key of selectedRowKeySet.value) {
if (rowByKey.value.has(key)) selectedCount++;