Dynamic Form Engine
Table of Contents
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
Introduction
DyForm is a dynamic form engine built on Vue 3 and TypeScript, implementing UI rendering driven by JSON Schema. The engine supports real-time data binding, form validation, conditional display, nested fields, and other advanced features through configurable form field definitions. The design philosophy of DyForm is to reduce repetitive code and improve development efficiency through declarative configuration, while maintaining high flexibility and extensibility.
Project Structure
The core file structure of the DyForm dynamic form engine is as follows:
Chart Source
Section Source
Core Components
DyForm Main Component
DyForm is the core component of the entire dynamic form engine, responsible for dynamically rendering form fields based on configuration parameters. This component adopts Vue 3's Composition API design, fully utilizing the advantages of the reactive system.
Key Features:
- JSON Schema Driven: Dynamically generates form fields via
formItemPropsconfiguration array - Reactive Data Binding: Automatically handles two-way data binding and state synchronization
- Built-in Component Mapping: Predefines mapping relationships for various common form components
- Custom Component Support: Supports extending custom components via
customWidgetMap - Internationalization Support: Automatically adapts form display to different language environments
Form Configuration Interface
interface FormItemPropType {
prop?: string | Ref<string>
label?: String | Ref<string>
rules?: any[] | Ref<any[]>
disabled?: boolean | Ref<boolean>
placeholder?: string | Ref<string>
type?: string | Ref<string>
width?: string | Ref<string>
el?: string | Component | DefineComponent | Ref<string>
options?: OptionItemType[] | any[] | Ref<any>
isTitle?: boolean
title?: string | Component
[key: string]: any | Ref<string>
}
Section Source
Architecture Overview
DyForm adopts a layered architecture design, forming a clear hierarchical structure from underlying components to upper-layer applications:
Chart Source
Detailed Component Analysis
Component Mapping Mechanism
DyForm implements a flexible component mapping mechanism through formItemElementMap:
const formItemElementMap: Record<string, any> = markRaw({
input: DyInput,
inputNumber: ElInputNumber,
select: Select,
selectInput: SelectInput,
flow: RelationFlowDialog,
variable: Variable,
textareaFlow: TextareaFlow,
switch: (props: PropType<any>, { attrs }: SetupContext) => {
return <el-switch {...attrs} />
},
})
This design allows developers to:
- Rapidly Extend: Add new form components by modifying the mapping table
- Component Reuse: Unify the usage of all form components
- Type Safety: Ensure component type correctness through TypeScript
Dynamic Form Rendering Flow
Chart Source
Conditional Display and Nested Fields
DyForm supports complex conditional display logic and nested field structures:
const isHide = has(item.isHide, 'value')
? item.isHide?.value
: item.isHide
return Component && !isHide ? (
<el-form-item
label={itemProps.label}
prop={itemProps.prop}
rules={itemProps.rules}
key={itemProps.prop + index}
>
<Component
modelValue={currentWidgetModel.value(itemProps.prop)}
onUpdate:modelValue={(val: string | number) =>
onUpdateModelValue(val, itemProps.prop)
}
/>
</el-form-item>
) : null
Section Source
Custom Component Extension
DyForm provides powerful capabilities for extending custom components:
const customWidgetMap = {
inputNumber: ElInputNumber,
flowItemKey: FlowContextDialog,
condition: (props: any, { attrs }: SetupContext) => (
<ConditionDialog
formItemProps={conditionFormItemProps.value}
conditionOptions={conditionOptions.value}
onConditionChange={onConditionChange}
onUpdateFormData={onUpdateFormData}
getCondition={getCondition}
v-model:formData={formData.value.Condition}
{...props}
{...attrs}
/>
),
}
This design enables DyForm to adapt to various complex business scenarios, from simple input boxes to complex condition selectors.
Section Source
Internationalization Support
DyForm has built-in robust internationalization support mechanisms:
const checkZh = (lang: string) => {
const languageStr = lang.toLowerCase()
if (languageStr.includes('zh')) return true
if (languageStr.includes('original')) return true
return false
}
const onLanguageChange = () => {
Language.useChange((language: any) => {
isZh.value = checkZh(language.lang)
})
}
Section Source
Dependency Analysis
The dependencies of DyForm reflect a good modular design:
Chart Source
Section Source
Performance Considerations
Reactivity Optimization
DyForm employs multiple performance optimization strategies:
- Computed Caching: Uses computed properties to cache calculation results
- markRaw Optimization: Uses markRaw for static objects to avoid unnecessary reactive tracking
- Lazy Initialization: Initializes form data and configuration on demand
const currentWidgetModel = computed(() => {
return (path: string) => {
if (path.includes('.')) {
const args = path.split('.')
return get(form.value, args)
}
return get(form.value, path)
}
})
Memory Management
- Event Cleanup: Automatically cleans up event listeners when components are unmounted
- Reference Management: Reasonably uses
refandreactiveto avoid memory leaks - Component Destruction: Timely destroys unneeded component instances
Troubleshooting Guide
Common Issues and Solutions
-
Form Validation Not Working
- Check if
rulesconfiguration is correct - Confirm
triggerevent settings - Verify data type matching
- Check if
-
Custom Component Not Rendering
- Confirm
customWidgetMapconfiguration - Check component import paths
- Verify component registration method
- Confirm
-
Data Binding Anomalies
- Check
propname consistency - Confirm
v-modelbinding syntax - Verify data type conversion
- Check
Debugging Tips
- Use Vue DevTools to monitor component state
- Enable strict mode to check data flow
- Use
console.logto track data changes
Section Source
Conclusion
The DyForm dynamic form engine is a powerful and elegantly designed form solution. Through its JSON Schema-driven approach, it achieves high flexibility and extensibility. This engine not only simplifies the form development process but also provides rich features, including conditional display, nested fields, and custom components.
Key Advantages:
- Configuration Driven: Rapidly generate complex forms via JSON configuration
- Type Safety: Complete TypeScript support ensures development quality
- Performance Optimization: Reasonable reactive design and caching mechanisms
- Easy Extension: Clear architecture facilitates feature extension and customization
- Internationalization Support: Built-in multi-language adaptation capabilities
DyForm provides an excellent solution for form development in modern Web applications, especially suitable for scenarios requiring frequent form structure adjustments or multi-language support.