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)