fix(@vben-core/form-ui): preserve array field focus

This commit is contained in:
Dream
2026-07-23 15:18:35 +08:00
parent 8d5a419c50
commit 1ac5ac3e82
2 changed files with 34 additions and 19 deletions

View File

@@ -485,6 +485,37 @@ describe('useVbenForm integration', () => {
});
});
it('preserves array row inputs and focus while editing', async () => {
const [Form] = useVbenForm({
schema: [
{
children: [
{
component: TestInput,
fieldName: 'name',
label: 'Name',
},
],
defaultValue: [{ name: 'Ada' }],
fieldName: 'contacts',
type: 'array',
},
],
});
const wrapper = mount(Form, { attachTo: document.body });
wrappers.push(wrapper);
await flushPromises();
const input = wrapper.get('input');
const inputElement = input.element;
inputElement.focus();
await input.setValue('Ada Lovelace');
await flushPromises();
expect(wrapper.get('input').element).toBe(inputElement);
expect(document.activeElement).toBe(inputElement);
});
it('scopes resolve dependencies to array rows', async () => {
const resolve = vi.fn(({ schema }: Record<string, any>) => ({
componentProps: {

View File

@@ -10,7 +10,7 @@ import {
VbenIconButton,
VbenRenderContent,
} from '@vben-core/shadcn-ui';
import { cn, isObject, set } from '@vben-core/shared/utils';
import { cn, set } from '@vben-core/shared/utils';
import { injectRenderFormProps } from '../form-render/context';
import FormField from '../form-render/form-field.vue';
@@ -72,8 +72,6 @@ if (!form) {
}
const formActions = form;
const arrayValue = formActions.useFieldValue(props.name);
const rowKeys = new WeakMap<object, string>();
let nextRowKey = 0;
const fields = computed<Record<string, any>[]>(() => {
return Array.isArray(arrayValue.value) ? arrayValue.value : [];
@@ -124,20 +122,6 @@ function removeRow(index: number) {
void formActions.removeFieldValue(arrayPath.value, index);
}
function getRowKey(row: Record<string, any>, index: number) {
if (!isObject(row)) {
return `${arrayPath.value}-${index}`;
}
const existingKey = rowKeys.get(row);
if (existingKey) {
return existingKey;
}
nextRowKey += 1;
const key = `${arrayPath.value}-${nextRowKey}`;
rowKeys.set(row, key);
return key;
}
function rowSchemas(index: number) {
return props.schema.map((col) =>
createArrayChildSchema(col as never, {
@@ -179,8 +163,8 @@ function rowSchemas(index: number) {
</div>
<div
v-for="(entry, index) in fields"
:key="getRowKey(entry, index)"
v-for="(_, index) in fields"
:key="`${arrayPath}-${index}`"
class="border-border/60 border-b p-3 last:border-b-0 sm:grid sm:p-0"
:style="gridStyle"
>