Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Give agents more agency

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    Dexploarer

    vue-component-generator

    Dexploarer/vue-component-generator
    Coding
    4

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Generates Vue 3 components using Composition API, TypeScript, proper props definition, and best practices. Use when creating Vue components or building Vue UI.

    SKILL.md

    Vue.js Component Generator Skill

    Expert at creating modern Vue 3 components with Composition API and TypeScript.

    When to Activate

    • "create a Vue component"
    • "generate Vue 3 component for [feature]"
    • "build a [component] in Vue"
    • "scaffold Vue UI component"

    Component Structure

    Single File Component (SFC)

    <template>
      <div :class="['container', props.className]">
        <h2 class="title">{{ props.title }}</h2>
    
        <div v-if="isLoading" class="loading">
          Loading...
        </div>
    
        <div v-else class="content">
          <slot />
    
          <button
            v-if="props.showAction"
            @click="handleAction"
            class="action-button"
          >
            {{ actionLabel }}
          </button>
        </div>
      </div>
    </template>
    
    <script setup lang="ts">
    import { ref, computed, onMounted, watch } from 'vue';
    
    // Props
    interface Props {
      title: string;
      showAction?: boolean;
      className?: string;
      items?: Item[];
    }
    
    const props = withDefaults(defineProps<Props>(), {
      showAction: false,
      className: '',
      items: () => [],
    });
    
    // Emits
    interface Emits {
      (e: 'action-clicked'): void;
      (e: 'update:modelValue', value: string): void;
    }
    
    const emit = defineEmits<Emits>();
    
    // State
    const isLoading = ref(false);
    const internalValue = ref('');
    
    // Computed
    const actionLabel = computed(() => {
      return isLoading.value ? 'Processing...' : 'Click Me';
    });
    
    // Methods
    const handleAction = () => {
      emit('action-clicked');
    };
    
    const loadData = async () => {
      isLoading.value = true;
      try {
        // Fetch data
      } finally {
        isLoading.value = false;
      }
    };
    
    // Lifecycle
    onMounted(() => {
      loadData();
    });
    
    // Watchers
    watch(() => props.items, (newItems) => {
      console.log('Items changed:', newItems);
    }, { deep: true });
    
    // Expose (optional - for parent template refs)
    defineExpose({
      loadData,
    });
    </script>
    
    <style scoped>
    .container {
      padding: 1rem;
      border-radius: 0.5rem;
      background-color: var(--background);
    }
    
    .title {
      margin-bottom: 1rem;
      font-size: 1.5rem;
      font-weight: 600;
    }
    
    .loading {
      display: flex;
      justify-content: center;
      padding: 2rem;
    }
    
    .action-button {
      padding: 0.5rem 1rem;
      border-radius: 0.25rem;
      background-color: var(--primary);
      color: white;
      border: none;
      cursor: pointer;
    }
    
    .action-button:hover {
      opacity: 0.9;
    }
    </style>
    

    Component Patterns

    Simple Presentational Component

    <template>
      <button
        :class="['btn', `btn-${variant}`]"
        :disabled="disabled"
        @click="$emit('click')"
      >
        {{ label }}
      </button>
    </template>
    
    <script setup lang="ts">
    interface Props {
      label: string;
      variant?: 'primary' | 'secondary';
      disabled?: boolean;
    }
    
    withDefaults(defineProps<Props>(), {
      variant: 'primary',
      disabled: false,
    });
    
    defineEmits<{
      (e: 'click'): void;
    }>();
    </script>
    

    Form Input with v-model

    <template>
      <div class="input-group">
        <label :for="inputId">{{ label }}</label>
        <input
          :id="inputId"
          :type="type"
          :value="modelValue"
          @input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
          :placeholder="placeholder"
        />
        <span v-if="error" class="error">{{ error }}</span>
      </div>
    </template>
    
    <script setup lang="ts">
    interface Props {
      modelValue: string;
      label: string;
      type?: string;
      placeholder?: string;
      error?: string;
    }
    
    withDefaults(defineProps<Props>(), {
      type: 'text',
      placeholder: '',
      error: '',
    });
    
    defineEmits<{
      (e: 'update:modelValue', value: string): void;
    }>();
    
    const inputId = `input-${Math.random().toString(36).slice(2)}`;
    </script>
    

    Composable for Data Fetching

    // composables/useUsers.ts
    import { ref } from 'vue';
    
    export interface User {
      id: number;
      name: string;
      email: string;
    }
    
    export function useUsers() {
      const users = ref<User[]>([]);
      const loading = ref(false);
      const error = ref<string | null>(null);
    
      const fetchUsers = async () => {
        loading.value = true;
        error.value = null;
    
        try {
          const response = await fetch('/api/users');
          users.value = await response.json();
        } catch (err) {
          error.value = (err as Error).message;
        } finally {
          loading.value = false;
        }
      };
    
      return {
        users,
        loading,
        error,
        fetchUsers,
      };
    }
    

    File Structure

    ComponentName/
    ├── ComponentName.vue           # Component SFC
    ├── ComponentName.spec.ts       # Unit tests
    ├── composables/
    │   └── useComponentLogic.ts   # Composable logic (if complex)
    ├── types.ts                   # TypeScript types
    └── index.ts                   # Export
    

    Testing Pattern

    // ComponentName.spec.ts
    import { mount } from '@vue/test-utils';
    import ComponentName from './ComponentName.vue';
    
    describe('ComponentName', () => {
      it('renders with required props', () => {
        const wrapper = mount(ComponentName, {
          props: {
            title: 'Test Title',
          },
        });
    
        expect(wrapper.text()).toContain('Test Title');
      });
    
      it('emits event on button click', async () => {
        const wrapper = mount(ComponentName, {
          props: {
            title: 'Test',
            showAction: true,
          },
        });
    
        await wrapper.find('.action-button').trigger('click');
        expect(wrapper.emitted('action-clicked')).toBeTruthy();
      });
    });
    

    Best Practices

    • Use Composition API with <script setup>
    • Define props with TypeScript interfaces
    • Use withDefaults for default values
    • Define emits with TypeScript
    • Use computed for derived state
    • Keep template logic simple
    • Use composables for reusable logic
    • Scoped styles by default
    • Proper TypeScript typing
    • Test component behavior

    Output Checklist

    • ✅ Component .vue file created
    • ✅ Props properly typed
    • ✅ Emits defined
    • ✅ Tests created
    • ✅ Composables extracted (if needed)
    • ✅ Accessibility considered
    • 📝 Usage example provided
    Recommended Servers
    OpenZeppelin
    OpenZeppelin
    MantleKit Launch Planner
    MantleKit Launch Planner
    Nanobanana
    Nanobanana
    Repository
    dexploarer/claudius-skills
    Files