anirbmuk
/
vue-dynamic-form
Dynamic and reactive form generation using Vue3
This article intends to demonstrate dynamic and reactive form generation based on user-defined configurations.
Overview
This is a Vue 3 application that demonstrates dynamic form generation based on user-defined configurations. The application allows users to specify how many input fields and select drop-downs they want, and then dynamically creates a form with the specified number of fields.
Project Structure
vue-dynamic-form/
├── src/
│ ├── components/
│ │ ├── FormDefinition.vue # Form configuration interface
│ │ └── FormImplementation.vue # Dynamic form renderer
│ ├── types/
│ │ └── form-definition.d.ts # TypeScript type definitions
│ ├── App.vue # Main application component
│ └── main.ts # Application entry point
├── package.json
└── README.md
Core Concepts
1. Form Definition Type
The application uses a simple type definition to specify form structure:
export type FormDefinition = {
input: number; // Number of text input fields
select: number; // Number of select dropdown fields
}
2. Component Architecture
FormDefinition.vue (Configuration Component)
- Purpose: Provides UI for users to specify form structure
-
Features:
- Number inputs for input and select field counts
- Real-time validation (minimum 0)
- Emits updates to parent component
- Props: Receives current form definition
-
Events: Emits
update:form-definition
when configuration changes
FormImplementation.vue (Dynamic Form Renderer)
- Purpose: Dynamically renders form fields based on configuration
-
Key Features:
- Reactive field generation
- Memory-efficient ref management
- Automatic cleanup of unused fields
Dynamic Form Generation Logic
The FormImplementation.vue
component uses a sophisticated reactive system:
- Reactive State Management:
// Reactive state management for dynamic form fields
// objectRefs: Stores reactive refs for each form field (input-1, input-2, select-1, etc.)
const objectRefs: Record<string, Ref<string>> = {};
// objectRefKeys: Reactive Set to track which keys currently exist
// Used for template iteration and cleanup logic
const objectRefKeys = reactive<Set<string>>(new Set<string>());
// objectRefsList: Alternative array representation of refs (currently unused)
// Could be used for bulk operations or debugging
const objectRefsList = reactive<Ref<string>[]>([])
-
Watcher-Based Field Management:
- Watches for changes in the
count
prop - Creates new reactive refs for each required field
- Removes unused refs to prevent memory leaks
- Maintains field state across re-renders
- Watches for changes in the
-
Field Creation Strategy:
- Uses unique keys (
input-1
,input-2
,select-1
, etc.) - Only creates new refs when they don't exist
- Preserves existing field values during re-renders
- Uses unique keys (
Memory Management
The application implements careful memory management:
- Selective Creation: Only creates refs for fields that don't exist
- Cleanup Logic: Removes refs for fields no longer needed
- State Preservation: Maintains field values during configuration changes
Template Rendering
The template uses Vue's reactive system effectively:
<!-- Dynamic input fields -->
<div v-for="i in count.input" :key="`input-${i}`" class="form-group">
<input v-model="objectRefs[`input-${i}`].value" />
</div>
<!-- Dynamic select fields -->
<div v-for="j in count.select" :key="`select-${j}`" class="form-group">
<select v-model="objectRefs[`select-${j}`].value">
<!-- Options -->
</select>
</div>
Usage Flow
- Initial State: Application starts with 0 input and 0 select fields
-
Configuration: User adjusts counts in
FormDefinition
component -
Dynamic Generation:
FormImplementation
component creates corresponding fields - Real-time Updates: Form updates immediately as configuration changes
- State Persistence: Field values are preserved during configuration changes
- Memory Management: When components are removed, the associated refs are also deleted, to prevent memory leak.
——-
Cheers :-)
Anirban Mukherjee
Top comments (0)