Three modes, one owner
Create, edit, and detail share one form instance inside the dialog or page.
load('edit', detail) rebases reset and dirty state.
Vue 2.7 + Vue 3 · Keep your UI library
Keep Element, Naive UI, or Ant Design Vue. vformjs standardizes create, edit, detail, validation, linkage, arrays, and server errors without replacing your components.
Build the first formTry the live state
Start with @vformjs/element-plus. Drop to useForm only when you need a custom host.
The gap between UI and business state
Admin projects keep rewriting mode switches, reset baselines, submit guards, conditional rules, list keys, and API error handling. vformjs keeps the host Form in charge of visual validation and gives the repeated lifecycle one typed API.
load('create' | 'edit' | 'detail')dirty + changedPathslist('contacts')submit() + submittingwhen + whenRulesLive product state
Element PlusThis small form runs the same baseline, dirty, server-error, and read-only semantics exposed by the public API.
A thin orchestration layer
Each API exists to remove a repeated production concern. The library does not ship replacement inputs or a second design system.
Create, edit, and detail share one form instance inside the dialog or page.
load('edit', detail) rebases reset and dirty state.
Element, Naive UI, and Antd keep their own rules, red text, and focus behavior.
Adapters bridge validate, clear, and scroll.
API field errors stay reactive and clear when their field changes.
setErrors() → errors → scrollToFirstError().
Keep native templates while centralizing conditional state and dependent options.
when, whenRules, and linkage remain plain TypeScript.
Append, move, replace, and remove nested rows without using array indexes as keys.
list('items') exposes stable fields.
Use Zod for schema-only validation and parsed submit output.
The UI adapter remains optional for headless validation.
The short path
The recommended Element Plus entry configures the adapter and infers the model type from defaults.
Defaults infer model and submit types.
useElForm({ defaults, rules, onSubmit })One binding wires ref, model, and rules.
<el-form v-bind="form.host">Load records, submit, reset, and inspect dirty state.
form.load('edit', detail)Pick the right layer
A form library decision gets easier when state ownership is explicit.
| Option | State and validation | CRUD lifecycle | Good fit when |
|---|---|---|---|
| Native UI Form | Host-owned | Hand-written per screen | The project has only a few simple forms |
| vformjs | Host validation + shared state | Built in | Admin screens repeat across an existing UI library |
| vee-validate / Vuelidate | Independent form engine | Application-defined | The team wants field-level headless control |
| FormKit / FormCreate | Component or schema runtime | Framework-owned | The team wants generated or low-code forms |
Do not bind vformjs and another complete form engine to the same fields. Pick one state owner.
A safe place to start
Keep the business components. Standardize mode, reset, submit, and errors, then decide whether the layer earns a place in the next screen.