DEV Community

Anirban Mukherjee
Anirban Mukherjee

Posted on

Vue - build dynamic reactive form

GitHub logo 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.


Generate Preview


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
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. 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>[]>([])
Enter fullscreen mode Exit fullscreen mode
  1. 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
  2. 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

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>
Enter fullscreen mode Exit fullscreen mode

Usage Flow

  1. Initial State: Application starts with 0 input and 0 select fields
  2. Configuration: User adjusts counts in FormDefinition component
  3. Dynamic Generation: FormImplementation component creates corresponding fields
  4. Real-time Updates: Form updates immediately as configuration changes
  5. State Persistence: Field values are preserved during configuration changes
  6. Memory Management: When components are removed, the associated refs are also deleted, to prevent memory leak.

——-

Cheers :-)
Anirban Mukherjee

Top comments (0)