基于vue3.0和element-plus的组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

3.4 KiB

useModifyForm

Form open/edit/add flow with dialog state and value normalization.

Purpose

Manages form dialog lifecycle including openAdd, openEdit, close operations with automatic value normalization for dict fields and proper cleanup.

Signature

export function useModifyForm(options: Options): {
  flagOnClose: null;
  flagOnAdd: "add";
  flagOnEdit: "edit";
  data: {
    dialog: any;
    model: Record<string, any>;
  };
  clearModel: () => void;
  assignModel: (newModel: Record<string, any>) => void;
  openAdd: (toAdd?: Record<string, any>) => void;
  openEdit: (toEdit: Record<string, any>) => void;
  close: () => void;
  onConfirm: () => Promise<void>;
  onCancel: () => Promise<void>;
}

Options Interface

interface Options {
  props?: FormProp[];
  formRef?: Ref<any>;
  handleAdd?: (value) => Promise<void>;
  handleEdit?: (value) => Promise<void>;
  handleCancel?: () => Promise<void>;
  handleError?: (kind: "validation" | "internal", err?) => void;
  handleClose?: () => void;
  init?: any;
  extraProps?: string[] | "any" | ((code: string) => boolean);
}

FormProp Interface

export interface FormProp {
  code: string;
  name?: string;
  i18n?: string;
  dict?: string;
  slot?: boolean;
  [others: string]: any;
}

Dialog Flow

openAdd() ──────► dialog = "add"
                       │
                       ▼
                  onConfirm() ──► handleAdd(value) ──► close()
                       │
                  onCancel() ───────────────────────────► close()
                       │
openEdit() ──────► dialog = "edit"
                       │
                       ▼
                  onConfirm() ──► handleEdit(value) ──► close()
                       │
                  onCancel() ───────────────────────────► close()

Usage Pattern

// Example: plugs/composables/useModifyForm.ts
const form = useModifyForm({
  props: [
    { code: "name", i18n: "user.name" },
    { code: "status", dict: "statusDict" },
  ],
  formRef,
  init: { status: 1 },
  handleAdd: async (value) => { await api.create(value); },
  handleEdit: async (value) => { await api.update(value); },
  handleClose: () => { formRef.value?.resetFields(); },
});

form.openAdd({ name: "New User" });
form.openEdit({ id: 1, name: "Updated User" });

Value Normalization

The composable normalizes model values on assignment:

  1. Dict fields: Parse string dict values to integers if numeric
  2. Extra props: Filter allowed props based on extraProps setting
  3. Null removal: Exclude null/undefined values from model

Key Implementation Details

  1. Dialog flag pattern: Uses string flags ("add", "edit", null) to track dialog state
  2. Model clearing: Uses clearAndAssign utility to reset model without losing reactivity
  3. Form validation: Calls clearValidate() on formRef when opening dialogs
  4. Deep copy: Uses deepCopy(toRaw()) before passing to handlers

Dependencies

  • vue - reactive, toRaw
  • plugs/element - showMessage
  • plugs/util/objectUtil - clearAndAssign, deepCopy

Anti-patterns

  • Do not directly mutate data.model; use assignModel() or clearModel()
  • Do not skip calling onConfirm() on submit; dialog state tracking depends on it