Files
eveAI/REFACTORING_PATTERN.md

3.3 KiB

Vue 3 Component Refactoring Pattern

Successfully Applied to: LanguageSelector

This document outlines the pattern for refactoring Vue components from the problematic renderComponent() approach to proper Vue 3 templates.

The Problem

Components were using both Vue templates AND manual DOM manipulation via renderComponent() methods, which caused conflicts with Vue's reactivity system.

The Solution Pattern

1. Component File Changes

Remove these problematic elements:

  • renderComponent() method (manual DOM manipulation)
  • render() fallback method
  • Call to this.renderComponent() in mounted() lifecycle

Keep these Vue elements:

  • template: with proper Vue directives (v-model, @change, v-for, etc.)
  • name, props, data(), methods, mounted() structure
  • Vue event handling ($emit, @change)

2. Chat-client.js Changes

Remove fallback logic:

  • Remove try/catch blocks that attempt renderComponent() as fallback
  • Remove manual DOM manipulation fallbacks
  • Keep only clean Vue mounting: app.mount(container)

3. Testing Pattern

Validation steps:

  1. Build project successfully (npm run build)
  2. Verify renderComponent() methods removed
  3. Verify Vue template structure intact
  4. Verify fallback logic removed from chat-client.js
  5. Test component functionality in browser

Example: LanguageSelector Before/After

Before (Problematic):

mounted() {
    this.renderComponent(); // ❌ Manual DOM manipulation
    this.$emit('language-changed', this.selectedLanguage);
},
methods: {
    renderComponent() { // ❌ Manual DOM manipulation
        const container = document.getElementById('language-selector-container');
        container.innerHTML = `...`; // Direct DOM manipulation
    }
},
template: `...`, // ✅ Vue template (but overridden by renderComponent)
render() { // ❌ Fallback method
    return document.createElement('div');
}

After (Clean Vue 3):

mounted() {
    // ✅ Only Vue lifecycle logic
    this.$emit('language-changed', this.selectedLanguage);
},
methods: {
    changeLanguage(languageCode) {
        // ✅ Only Vue reactive logic
        this.selectedLanguage = languageCode;
        this.$emit('language-changed', languageCode);
    }
},
template: `
    <div class="language-selector">
        <select v-model="selectedLanguage" @change="changeLanguage(selectedLanguage)">
            <option v-for="lang in getAvailableLanguages()" :key="lang.code" :value="lang.code">
                {{ lang.flag }} {{ lang.name }}
            </option>
        </select>
    </div>
` // ✅ Clean Vue template with reactivity

Benefits Achieved

  • Proper Vue 3 reactivity
  • Cleaner, maintainable code
  • Better debugging with Vue DevTools
  • No DOM manipulation conflicts
  • Modern Vue patterns
  • Successful build without errors

Next Components to Refactor

Based on previous analysis, these components need the same treatment:

  • ChatInput.js
  • MessageHistory.js
  • ChatMessage.js
  • TypingIndicator.js
  • ProgressTracker.js
  • FormField.js
  • DynamicForm.js
  • ChatApp.js

Success Metrics

  • Component builds without errors
  • No renderComponent() methods in codebase
  • No fallback logic in chat-client.js
  • Vue templates work with proper reactivity
  • All functionality preserved