Skip to content

Commit

Permalink
fix(schema-form): nested field setting failed
Browse files Browse the repository at this point in the history
  • Loading branch information
buqiyuan committed Mar 9, 2024
1 parent d4837c6 commit 58d99f7
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 71 deletions.
11 changes: 5 additions & 6 deletions src/components/core/draggable-modal/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div ref="modalWrapRef" class="draggable-modal" :class="{ fullscreen: fullscreenModel }">
<Modal
v-bind="omit(props, ['open', 'onCancel', 'onOk', 'onUpdate:open'])"
v-model:open="visibleModel"
v-model:open="openModel"
:mask-closable="false"
:get-container="() => modalWrapRef"
:width="innerWidth || width"
Expand Down Expand Up @@ -39,11 +39,10 @@
</template>

<script lang="ts" setup>
import { ref, watch, nextTick } from 'vue';
import { ref, watch, nextTick, defineModel } from 'vue';
import { useRoute } from 'vue-router';
import { modalProps } from 'ant-design-vue/es/modal/Modal';
import { CloseOutlined, FullscreenOutlined, FullscreenExitOutlined } from '@ant-design/icons-vue';
import { useVModel } from '@vueuse/core';
import { throttle, omit } from 'lodash-es';
import { Modal, Space } from 'ant-design-vue';
Expand All @@ -62,7 +61,7 @@
const emit = defineEmits(['update:open', 'update:fullscreen', 'ok', 'cancel']);
const route = useRoute();
const visibleModel = useVModel(props, 'open');
const openModel = defineModel<boolean>('open');
const fullscreenModel = ref(props.fullscreen);
const innerWidth = ref('');
Expand All @@ -83,7 +82,7 @@
const modalWrapRef = ref<HTMLDivElement>();
const closeModal = () => {
visibleModel.value = false;
openModel.value = false;
emit('cancel');
};
Expand Down Expand Up @@ -274,7 +273,7 @@
inited = true;
};
watch(visibleModel, async (val) => {
watch(openModel, async (val) => {
if ((val && Object.is(inited, false)) || props.destroyOnClose) {
initDrag();
}
Expand Down
27 changes: 14 additions & 13 deletions src/components/core/schema-form/src/hooks/useFormEvents.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unref, toRaw } from 'vue';
import { cloneDeep, isNil, uniqBy } from 'lodash-es';
import { cloneDeep, isNil, set, uniqBy, unset } from 'lodash-es';
import dayjs from 'dayjs';
import { dateItemType, handleInputNumberValue } from '../helper';
import type { UnwrapFormSchema } from '../types/form';
Expand Down Expand Up @@ -52,7 +52,7 @@ export function useFormEvents(formActionContext: UseFormActionContext) {
/**
* @description: 设置表单字段值
*/
async function setFieldsValue(values: Recordable): Promise<void> {
async function setFieldsValue(values: Recordable) {
const schemas = unref(formSchemasRef);
// @ts-ignore
const fields = schemas.map((item) => item.field).filter(Boolean);
Expand All @@ -76,22 +76,23 @@ export function useFormEvents(formActionContext: UseFormActionContext) {
for (const ele of value) {
arr.push(ele ? dayjs(ele) : null);
}
formModel[key] = arr;
set(formModel, key, arr);
} else {
const { componentProps } = schema || {};
let _props = componentProps as any;
if (isFunction(componentProps)) {
_props = _props({ formPropsRef, formModel });
}
formModel[key] = value ? (_props?.valueFormat ? value : dayjs(value)) : null;
set(formModel, key, value ? (_props?.valueFormat ? value : dayjs(value)) : null);
}
} else {
formModel[key] = value;
set(formModel, key, value);
}
validKeys.push(key);
}
});
validateFields(validKeys);
// console.log('formModel', formModel);
await validateFields(validKeys).catch((_) => {});
}

async function resetSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) {
Expand All @@ -115,16 +116,14 @@ export function useFormEvents(formActionContext: UseFormActionContext) {

if (!prefixField || index === -1 || first) {
first ? schemaList.unshift(schemaItem) : schemaList.push(schemaItem);
formModel[schemaItem.field] = schemaItem.defaultValue;
formPropsRef.value.schemas = schemaList;
return;
}
if (index !== -1) {
schemaList.splice(index + 1, 0, schemaItem);
}
formModel[schemaItem.field] = schemaItem.defaultValue;
formPropsRef.value.schemas = schemaList;
_setDefaultValue(formPropsRef.value.schemas);
setDefaultValue(formPropsRef.value.schemas);
}

/**
Expand All @@ -145,7 +144,7 @@ export function useFormEvents(formActionContext: UseFormActionContext) {
if (isString(field)) {
const index = schemaList.findIndex((schema) => schema.field === field);
if (index !== -1) {
Reflect.deleteProperty(formModel, field);
unset(formModel, field);
schemaList.splice(index, 1);
}
}
Expand Down Expand Up @@ -211,11 +210,12 @@ export function useFormEvents(formActionContext: UseFormActionContext) {
schemas.push(val);
}
});
_setDefaultValue(updatedSchemas);

setDefaultValue(updatedSchemas);
formPropsRef.value.schemas = uniqBy<UnwrapFormSchema>(schemas, 'field');
};

function _setDefaultValue(data: FormSchema | FormSchema[]) {
function setDefaultValue(data: FormSchema | FormSchema[]) {
let schemas: FormSchema[] = [];
if (isObject(data)) {
schemas.push(data as FormSchema);
Expand Down Expand Up @@ -245,7 +245,7 @@ export function useFormEvents(formActionContext: UseFormActionContext) {
resetFunc && isFunction(resetFunc) && (await resetFunc());

Object.keys(formModel).forEach((key) => {
formModel[key] = defaultFormValues[key];
set(formModel, key, defaultFormValues[key]);
});

emit('reset', formModel);
Expand Down Expand Up @@ -314,5 +314,6 @@ export function useFormEvents(formActionContext: UseFormActionContext) {
resetFields,
setFieldsValue,
scrollToField,
setDefaultValue,
};
}
34 changes: 7 additions & 27 deletions src/components/core/schema-form/src/hooks/useFormMethods.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
import { unref } from 'vue';
import { set } from 'lodash-es';
import { set, unset } from 'lodash-es';
import type { FormState } from './useFormState';
import type { SchemaFormProps } from '../schema-form';
import { deepMerge } from '@/utils/';
import { isFunction, isDef, isObject, isArray, isString } from '@/utils/is';
import { isFunction, isObject, isArray, isString } from '@/utils/is';
import { dateUtil } from '@/utils/dateUtil';

type UseFormMethodsContext = FormState;

export type FormMethods = ReturnType<typeof useFormMethods>;

export const useFormMethods = (formMethodsContext: UseFormMethodsContext) => {
const {
compRefMap,
formModel,
formPropsRef,
cacheFormModel,
defaultFormValues,
schemaFormRef,
getFormProps,
} = formMethodsContext;
const { compRefMap, formModel, formPropsRef, cacheFormModel, schemaFormRef, getFormProps } =
formMethodsContext;

// 将所有的表单组件实例保存起来, 方便外面通过表单组件实例操作
const setItemRef = (field: string) => {
Expand All @@ -32,8 +25,8 @@ export const useFormMethods = (formMethodsContext: UseFormMethodsContext) => {

// 设置某个字段的值
const setFormModel = (key: Key, value: any) => {
formModel[key] = value;
cacheFormModel[key] = value;
set(formModel, key, value);
set(cacheFormModel, key, value);
const { validateTrigger } = unref(getFormProps);
if (!validateTrigger || validateTrigger === 'change') {
schemaFormRef.value?.validateFields([key]);
Expand All @@ -42,7 +35,7 @@ export const useFormMethods = (formMethodsContext: UseFormMethodsContext) => {

// 删除某个字段
const delFormModel = (key: Key) => {
return Reflect.deleteProperty(formModel, key);
return unset(formModel, key);
};

const setSchemaFormProps = (formProps: Partial<SchemaFormProps>) => {
Expand Down Expand Up @@ -103,21 +96,8 @@ export const useFormMethods = (formMethodsContext: UseFormMethodsContext) => {
return values;
}

// 初始化数据
const initFormValues = () => {
unref(formPropsRef).schemas?.forEach((item) => {
const { defaultValue } = item;
if (isDef(defaultValue)) {
formModel[item.field] = defaultValue;
defaultFormValues[item.field] = defaultValue;
cacheFormModel[item.field] = defaultValue;
}
});
};

return {
setItemRef,
initFormValues,
setFormModel,
delFormModel,
setSchemaFormProps,
Expand Down
14 changes: 8 additions & 6 deletions src/components/core/schema-form/src/schema-form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
</template>

<script lang="ts" setup>
import { useAttrs } from 'vue';
import { useAttrs, onMounted } from 'vue';
import { pick } from 'lodash-es';
import { Form, Row } from 'ant-design-vue';
import SchemaFormItem from './schema-form-item.vue';
Expand Down Expand Up @@ -74,14 +74,11 @@
// 表单内部方法
const formMethods = useFormMethods({ ...formState });
const { initFormValues, handleFormValues } = formMethods;
// 初始化表单默认值
initFormValues();
const { handleFormValues } = formMethods;
// a-form表单事件二次封装和扩展
const formEvents = useFormEvents({ ...formState, emit, handleFormValues });
const { handleEnterPress } = formEvents;
const { handleEnterPress, setDefaultValue } = formEvents;
// 当前组件所有的状态和方法
const instance = {
Expand All @@ -101,4 +98,9 @@
createFormContext(instance);
defineExpose(instance);
onMounted(() => {
// 初始化表单默认值
setDefaultValue(formSchemasRef.value);
});
</script>
12 changes: 2 additions & 10 deletions src/components/core/schema-form/src/types/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,12 @@ type ComponentSchema<T extends object = Recordable> =
/** 表单组件属性 */
componentProps?:
| ComponentProps<K>
| {
(opt: RenderCallbackParams<T, ComponentProps<K>>): ComponentProps<K>;
requestResult: ComponentProps['requestResult'];
};
| ((opt: RenderCallbackParams<T, ComponentProps<K>>) => ComponentProps<K>);
};
}[ComponentType]
| {
component: CustomRenderFn<T> | ((opt: RenderCallbackParams<T>) => Component);
componentProps?:
| ComponentProps
| {
(opt: RenderCallbackParams<T>): ComponentProps;
requestResult: ComponentProps['requestResult'];
};
componentProps?: ComponentProps | ((opt: RenderCallbackParams<T>) => ComponentProps);
};

/** 表单项 */
Expand Down
2 changes: 1 addition & 1 deletion src/router/routes/modules/demos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const routes: Array<RouteRecordRaw> = [
meta: {
title: '英雄详情',
icon: 'ant-design:desktop-outlined',
hideInMenu: false,
hideInMenu: true,
keepAlive: false,
activeMenu: `${moduleName}-table-lol`,
},
Expand Down
7 changes: 0 additions & 7 deletions src/views/demos/tables/edit-row-table/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export type ListItemType = (typeof tableData)[number];
export const columns: TableColumn<ListItemType>[] = [
{
title: '姓名',

dataIndex: 'name',
sorter: true,
/** 默认开启编辑, 仅`editableType`为`cell`时有效 */
Expand All @@ -38,7 +37,6 @@ export const columns: TableColumn<ListItemType>[] = [
},
{
title: '性别',

dataIndex: 'gender',
/** 搜索表单配置 */
formItemProps: {
Expand Down Expand Up @@ -75,8 +73,6 @@ export const columns: TableColumn<ListItemType>[] = [
rules: [{ required: true, type: 'number', message: '请选择性别' }],
componentProps: ({ formInstance, formModel, tableRowKey }) => ({
onChange() {
console.log('formModel', formModel);

// 根据当前选择的性别,更新衣服可选项
formInstance?.updateSchema({
field: `${tableRowKey}.clothes`,
Expand All @@ -92,7 +88,6 @@ export const columns: TableColumn<ListItemType>[] = [
},
{
title: '衣服',

dataIndex: 'clothes',
formItemProps: {
component: 'Select',
Expand Down Expand Up @@ -136,7 +131,6 @@ export const columns: TableColumn<ListItemType>[] = [
},
{
title: '价格',

dataIndex: 'price',
editFormItemProps: {
component: 'InputNumber',
Expand All @@ -146,7 +140,6 @@ export const columns: TableColumn<ListItemType>[] = [
},
{
title: '状态',

dataIndex: 'status',
formItemProps: {
component: 'Select',
Expand Down
4 changes: 3 additions & 1 deletion src/views/system/role/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@
perm: 'system:role:update',
effect: 'disable',
},
onClick: () => openMenuModal(record),
onClick: () => {
openMenuModal(record);
},
},
{
label: '删除',
Expand Down

0 comments on commit 58d99f7

Please sign in to comment.