Files
Will Miao 32249d1886 feat: add Vue widget demo node and development support
- Add LoraManagerDemoNode to node mappings for Vue widget demonstration
- Update .gitignore to exclude Vue widget development artifacts (node_modules, .vite, dist)
- Implement automatic Vue widget build check in development mode with fallback handling
- Maintain pytest compatibility with proper import error handling
2026-01-10 17:45:26 +08:00

3.7 KiB

Vue Widgets for ComfyUI LoRA Manager

This directory contains the source code for Vue 3 + PrimeVue custom widgets for ComfyUI LoRA Manager.

Structure

vue-widgets/
├── src/                    # TypeScript/Vue source code
│   ├── main.ts            # Main entry point that registers extensions
│   └── components/        # Vue components
│       └── DemoWidget.vue # Example demo widget
├── package.json           # Dependencies and build scripts
├── vite.config.mts        # Vite build configuration
├── tsconfig.json          # TypeScript configuration
└── README.md             # This file

Development

Install Dependencies

cd vue-widgets
npm install

Build for Production

npm run build

This compiles the TypeScript/Vue code and outputs to ../web/comfyui/vue-widgets/.

Development Mode (Watch)

npm run dev

This builds the widgets in watch mode, automatically rebuilding when files change.

Type Checking

npm run typecheck

Creating a New Widget

1. Create the Python Node

Create a new node file in /py/nodes/your_node.py:

class YourCustomNode:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "your_widget_name": ("YOUR_WIDGET_TYPE", {}),
            }
        }

    RETURN_TYPES = ("STRING",)
    FUNCTION = "process"
    CATEGORY = "loramanager"

    def process(self, your_widget_name):
        # Process widget data
        return (str(your_widget_name),)

NODE_CLASS_MAPPINGS = {
    "YourCustomNode": YourCustomNode
}

2. Create the Vue Component

Create a new component in src/components/YourWidget.vue:

<template>
  <div class="your-widget-container">
    <!-- Your UI here using PrimeVue components -->
    <Button label="Click me" @click="handleClick" />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import Button from 'primevue/button'

const props = defineProps<{
  widget: { serializeValue?: (node: unknown, index: number) => Promise<unknown> }
  node: { id: number }
}>()

onMounted(() => {
  // Serialize widget data when workflow is saved
  props.widget.serializeValue = async () => {
    return { /* your data */ }
  }
})
</script>

<style scoped>
/* Your styles */
</style>

3. Register the Widget

In src/main.ts, add your widget registration:

import YourWidget from '@/components/YourWidget.vue'

// In getCustomWidgets()
YOUR_WIDGET_TYPE(node) {
  return createVueWidget(node, YourWidget, 'your-widget-name')
}

// In nodeCreated()
if (node.constructor?.comfyClass !== 'YourCustomNode') return

4. Register the Node

Add your node to __init__.py:

from .py.nodes.your_node import YourCustomNode

NODE_CLASS_MAPPINGS = {
    # ...
    "YourCustomNode": YourCustomNode
}

5. Build and Test

npm run build

Then restart ComfyUI and test your new widget!

Available PrimeVue Components

This project uses PrimeVue 4.x. Popular components include:

  • Button - Buttons with icons and variants
  • InputText - Text input fields
  • InputNumber - Number input with increment/decrement
  • Dropdown - Select dropdowns
  • Card - Card containers
  • DataTable - Data tables with sorting/filtering
  • Dialog - Modal dialogs
  • Tree - Tree view components
  • And many more! See PrimeVue Docs

Notes

  • Build output goes to ../web/comfyui/vue-widgets/ (gitignored)
  • The widget type name in Python (e.g., "YOUR_WIDGET_TYPE") must match the key in getCustomWidgets()
  • Widget data is serialized when the workflow is saved/executed via serializeValue()
  • ComfyUI's app.js is marked as external and not bundled