Cursor rules for Vue 3 development with Composition API, TypeScript, and Pinia state management.
.cursorrules in your project rootYou are an expert Vue 3 developer using Composition API with TypeScript.
## Component Structure
```vue
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { useUserStore } from '@/stores/user';
import type { User } from '@/types';
// Props with defaults
interface Props {
userId: string;
showAvatar?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
showAvatar: true,
});
// Emits with typing
const emit = defineEmits<{
(e: 'update', user: User): void;
(e: 'delete', id: string): void;
}>();
// State
const loading = ref(false);
const user = ref<User | null>(null);
// Store
const userStore = useUserStore();
// Computed
const fullName = computed(() => {
if (!user.value) return '';
return `${user.value.firstName} ${user.value.lastName}`;
});
// Methods
async function fetchUser() {
loading.value = true;
try {
user.value = await userStore.fetchUser(props.userId);
} finally {
loading.value = false;
}
}
function handleUpdate() {
if (user.value) {
emit('update', user.value);
}
}
// Lifecycle
onMounted(() => {
fetchUser();
});
</script>
<template>
<div class="user-card">
<div v-if="loading" class="skeleton" />
<template v-else-if="user">
<img v-if="showAvatar" :src="user.avatar" :alt="fullName" />
<h2>{{ fullName }}</h2>
<button @click="handleUpdate">Update</button>
</template>
</div>
</template>
<style scoped>
.user-card {
padding: 1rem;
border-radius: 0.5rem;
}
</style>
```
## Pinia Store
```typescript
// stores/user.ts
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import type { User } from '@/types';
import { api } from '@/lib/api';
export const useUserStore = defineStore('user', () => {
// State
const users = ref<Map<string, User>>(new Map());
const currentUserId = ref<string | null>(null);
// Getters
const currentUser = computed(() => {
if (!currentUserId.value) return null;
return users.value.get(currentUserId.value) ?? null;
});
const userList = computed(() => Array.from(users.value.values()));
// Actions
async function fetchUser(id: string): Promise<User> {
if (users.value.has(id)) {
return users.value.get(id)!;
}
const user = await api.get<User>(`/users/${id}`);
users.value.set(id, user);
return user;
}
async function updateUser(id: string, data: Partial<User>): Promise<User> {
const user = await api.patch<User>(`/users/${id}`, data);
users.value.set(id, user);
return user;
}
function setCurrentUser(id: string | null) {
currentUserId.value = id;
}
return {
users,
currentUser,
userList,
fetchUser,
updateUser,
setCurrentUser,
};
});
```
## Composables
```typescript
// composables/useAsync.ts
import { ref, type Ref } from 'vue';
interface UseAsyncReturn<T> {
data: Ref<T | null>;
loading: Ref<boolean>;
error: Ref<Error | null>;
execute: () => Promise<void>;
}
export function useAsync<T>(
fn: () => Promise<T>,
immediate = true
): UseAsyncReturn<T> {
const data = ref<T | null>(null) as Ref<T | null>;
const loading = ref(false);
const error = ref<Error | null>(null);
async function execute() {
loading.value = true;
error.value = null;
try {
data.value = await fn();
} catch (e) {
error.value = e instanceof Error ? e : new Error(String(e));
} finally {
loading.value = false;
}
}
if (immediate) {
execute();
}
return { data, loading, error, execute };
}
```Comprehensive Cursor rules for Next.js 14+ with App Router, including routing, layouts, and API patterns.
Cursor rules for TypeScript with strict type checking, advanced patterns, and best practices.
Cursor rules for Tailwind CSS development with responsive design, custom components, and dark mode.
Cursor
frontend
AI coding rules customize how Cursor generates and refactors code for your project. Follow these steps to install Vue 3 Composition API.
.cursor/rules, for Windsurf use .windsurfrulesComprehensive Cursor rules for Next.js 14+ with App Router, including routing, layouts, and API patterns.
Cursor rules for TypeScript with strict type checking, advanced patterns, and best practices.
Cursor rules for Tailwind CSS development with responsive design, custom components, and dark mode.