| name | vue-components |
| description | Build Vue 3 components with TypeScript and Tailwind using clean structure, composable logic, accessibility, and maintainable patterns. |
Writing Vue Components
You are an experienced Vue and TypeScript developer. You write components that are clean, readable, and easy to maintain. You optimize for clarity and simplicity.
Principles
- Keep components small and focused. Each component should do one thing and do it well. If a component becomes too long or complex, split it into smaller, composable components.
- Minimize logic inside components. Move business logic or data processing into separate composable functions (/composables), utilities, or services. This makes the component easier to test and understand.
- Favor computed properties and methods over template logic. Keep templates clean and declarative. Use computed properties or methods for any transformations or conditions, rather than inline logic in the template.
- Fail gracefully. Components should be fault-tolerant. If props or data are missing, null, or in an unexpected format, the component should handle it gracefully and provide sensible defaults or fallback UI.
- Use TypeScript effectively. Strongly type props, emits, and events. Leverage Vue's defineProps and defineEmits to ensure correct usage. Prefer explicit types to improve developer experience and catch errors early.
- Write testable code. Extract complex logic into pure functions that can be tested in isolation. Keep the component focused on rendering and user interaction.
- Destructure props instead of using props.property
- Consistent naming and structure.
- Use clear, descriptive names for components, props, and events.
- Stick to a consistent file structure (e.g., components, composables, utils).
- Keep the
Styling with Tailwind CSS
- Use Tailwind CSS utility classes for all styling. Avoid writing custom CSS unless necessary. Utility classes keep the styles consistent and colocated with the template.
- Keep class lists readable.
- Break long class lists into multiple lines for readability if needed.
- Use component-level abstractions when appropriate.
- If multiple components share the same styles, extract them into reusable Vue components or leverage Tailwind's @apply in minimal CSS files or scoped styles.
- Handle responsive and dark mode thoughtfully. Use Tailwind's responsive and dark mode variants consistently. Ensure components look good on different screen sizes and in both light/dark themes.
- Accessibility matters. Tailwind won't handle accessibility for you. Make sure you add semantic HTML, ARIA attributes where needed, and focus handling for interactive components.
Example Structure
<script setup lang="ts">
import { computed } from 'vue'
import { useItems } from '@/composables/useItems'
const { initialItems } = defineProps<{
initialItems?: Item[]
}>()
const { items } = useItems(props.initialItems || [])
/** We don't want to show the card when there's no item. */
const hasItems = computed(() => items.value.length > 0)
</script>
<template>
<div v-if="items.length" class="grid gap-4 md:grid-cols-2">
<ItemCard
v-for="item in items"
:key="item.id"
:item="item"
class="rounded-xl shadow p-4 bg-white dark:bg-gray-800"
/>
</div>
<p v-else class="text-center text-gray-500">No items available.</p>
</template>