بنقرة واحدة
vue-conventions
Vue 3 Composition API patterns with TypeScript, Pinia, composables, and performance
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Vue 3 Composition API patterns with TypeScript, Pinia, composables, and performance
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
RESTful API design patterns, HTTP standards, versioning, error handling, and documentation
Joomla 4/5 component development with MVC, services, plugins, and language handling
Joomla 3.x legacy patterns with JFactory, non-namespaced MVC, JDatabase, and plugin structure
Laravel best practices for Eloquent, controllers, validation, services, and testing
Performance optimization for PHP, JavaScript, databases, and caching strategies
PHP coding standards including strict typing, OOP patterns, error handling, and documentation
استنادا إلى تصنيف SOC المهني
| name | vue-conventions |
| description | Vue 3 Composition API patterns with TypeScript, Pinia, composables, and performance |
| license | MIT |
| compatibility | opencode |
| metadata | {"framework":"vue","version":"3.0+"} |
<script setup><script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useUserStore } from '@/stores/user'
import type { User } from '@/types'
// Props with defaults
const props = withDefaults(defineProps<{
userId: number
showAvatar?: boolean
}>(), {
showAvatar: true
})
// Emits with types
const emit = defineEmits<{
(e: 'update', user: User): void
(e: 'delete', id: number): void
}>()
// Reactive state
const is_loading = ref(false)
const error_message = ref<string | null>(null)
// Store
const user_store = useUserStore()
// Computed
const full_name = computed(() =>
`${user_store.current_user?.first_name} ${user_store.current_user?.last_name}`
)
// Methods
async function fetchUser(): Promise<void> {
is_loading.value = true
try {
await user_store.fetchUser(props.userId)
} catch (err) {
error_message.value = 'Failed to load user'
} finally {
is_loading.value = false
}
}
// Lifecycle
onMounted(() => {
fetchUser()
})
</script>
<template>
<div class="user-profile">
<div v-if="is_loading">Loading...</div>
<div v-else-if="error_message" class="error">{{ error_message }}</div>
<template v-else>
<img v-if="showAvatar" :src="user_store.current_user?.avatar" :alt="full_name">
<h2>{{ full_name }}</h2>
</template>
</div>
</template>
// composables/useApi.ts
import { ref, type Ref } from 'vue'
interface UseApiReturn<T> {
data: Ref<T | null>
error: Ref<string | null>
is_loading: Ref<boolean>
execute: () => Promise<void>
}
export function useApi<T>(url: string): UseApiReturn<T> {
const data = ref<T | null>(null) as Ref<T | null>
const error = ref<string | null>(null)
const is_loading = ref(false)
async function execute(): Promise<void> {
is_loading.value = true
error.value = null
try {
const response = await fetch(url)
if (!response.ok) throw new Error('Request failed')
data.value = await response.json()
} catch (err) {
error.value = err instanceof Error ? err.message : 'Unknown error'
} finally {
is_loading.value = false
}
}
return { data, error, is_loading, execute }
}
// stores/user.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { User } from '@/types'
export const useUserStore = defineStore('user', () => {
// State
const current_user = ref<User | null>(null)
const users = ref<User[]>([])
// Getters
const is_authenticated = computed(() => current_user.value !== null)
const active_users = computed(() => users.value.filter(u => u.is_active))
// Actions
async function fetchUser(id: number): Promise<void> {
const response = await fetch(`/api/users/${id}`)
current_user.value = await response.json()
}
function logout(): void {
current_user.value = null
}
return {
current_user,
users,
is_authenticated,
active_users,
fetchUser,
logout
}
})
<!-- Parent -->
<template>
<ChildComponent
:user="selected_user"
@update="handleUpdate"
@delete="handleDelete"
>
<template #header>
<h2>Custom Header</h2>
</template>
</ChildComponent>
</template>
<!-- Child with slots -->
<template>
<div>
<slot name="header">
<h2>Default Header</h2>
</slot>
<div>{{ user.name }}</div>
<button @click="$emit('update', user)">Update</button>
</div>
</template>
<script setup lang="ts">
import { defineAsyncComponent, shallowRef } from 'vue'
// Lazy load heavy components
const HeavyChart = defineAsyncComponent(() =>
import('@/components/HeavyChart.vue')
)
// Use shallowRef for large objects that don't need deep reactivity
const large_dataset = shallowRef<DataPoint[]>([])
</script>
<template>
<!-- v-if for rarely shown elements -->
<Modal v-if="is_modal_open" />
<!-- v-show for frequently toggled -->
<Tooltip v-show="is_hovering" />
<!-- Always use key with v-for -->
<UserCard
v-for="user in users"
:key="user.id"
:user="user"
/>
<!-- Suspense for async components -->
<Suspense>
<template #default>
<HeavyChart :data="chart_data" />
</template>
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
</template>
// types/index.ts
export interface User {
id: number
first_name: string
last_name: string
email: string
avatar?: string
is_active: boolean
created_at: string
}
export interface ApiResponse<T> {
data: T
meta?: {
total: number
page: number
per_page: number
}
}
// Props type
export interface UserCardProps {
user: User
show_actions?: boolean
}
// Global error handler in main.ts
app.config.errorHandler = (err, instance, info) => {
console.error('Global error:', err)
// Send to error tracking service
}
// Component-level
import { onErrorCaptured } from 'vue'
onErrorCaptured((err, instance, info) => {
error_message.value = 'Something went wrong'
return false // Prevent propagation
})
v-html only with sanitized content (DOMPurify)