Generate reusable Vue 3 composable functions following best practices from official Vue documentation
This skill has safety concerns that you should review before use. Some patterns were detected that may pose a risk.Safety score: 60/100.
KillerSkills scans all public content for safety. Use caution before installing or executing flagged content.
Generate production-ready Vue 3 composable functions that follow official Vue.js conventions and best practices for encapsulating and reusing stateful logic.
This skill helps you create Vue 3 composable functions that leverage the Composition API to encapsulate stateful logic. Composables are reusable functions that can manage reactive state, lifecycle hooks, and side effects in a modular way.
When the user requests a Vue 3 composable, follow these steps:
1. **Understand the Requirements**
- Ask what functionality the composable should provide
- Determine if it needs to accept reactive arguments (refs, getters, or plain values)
- Identify what state and methods should be exposed
- Clarify any async operations or side effects needed
2. **Design the Composable Structure**
- Use the `use` prefix naming convention (e.g., `useMouse`, `useFetch`, `useEventListener`)
- Plan what reactive state needs to be managed with `ref()` or `computed()`
- Identify lifecycle hooks needed (`onMounted`, `onUnmounted`, `watchEffect`, `watch`)
- Determine the return value structure (plain object with refs)
3. **Implement Following Best Practices**
**Naming:**
- Use camelCase with "use" prefix (e.g., `useMouseTracker`)
**Input Arguments:**
- Accept refs, getters, or plain values for flexibility
- Use `toValue()` to normalize input arguments
- Watch reactive inputs with `watchEffect()` or `watch()` when needed
**State Management:**
- Use `ref()` for reactive state (NOT `reactive()` for return values)
- Encapsulate all state management within the composable
**Side Effects:**
- Set up side effects in `onMounted()`
- Clean up in `onUnmounted()`
- Use `watchEffect()` for reactive side effects
**Return Values:**
- Return a plain object containing multiple refs
- This allows destructuring while maintaining reactivity
- Example: `return { x, y, error, loading }`
4. **Generate the Composable File**
Create a file with this structure:
```typescript
import { ref, onMounted, onUnmounted, watchEffect, toValue } from 'vue'
/**
* Composable description
* @param input - Description of parameters
* @returns Object with reactive refs
*/
export function useYourFeature(input) {
// State encapsulated and managed by the composable
const state = ref(initialValue)
const error = ref(null)
// Internal functions that update managed state
function updateState(newValue) {
state.value = newValue
}
// Lifecycle hooks for side effects
onMounted(() => {
// Setup code
})
onUnmounted(() => {
// Cleanup code
})
// Reactive effects if needed
watchEffect(() => {
const normalizedInput = toValue(input)
// React to input changes
})
// Expose managed state and methods
return {
state,
error,
updateState
}
}
```
5. **Generate Usage Example**
Create a component example showing how to use the composable:
```vue
<script setup>
import { useYourFeature } from './composables/useYourFeature'
const { state, error, updateState } = useYourFeature()
</script>
<template>
<div v-if="error">Error: {{ error.message }}</div>
<div v-else>State: {{ state }}</div>
</template>
```
6. **Add TypeScript Types (if applicable)**
```typescript
interface FeatureOptions {
// options
}
interface FeatureReturn {
state: Ref<StateType>
error: Ref<Error | null>
updateState: (value: StateType) => void
}
export function useYourFeature(
options?: FeatureOptions
): FeatureReturn {
// implementation
}
```
7. **Handle Common Patterns**
**Async State:**
```typescript
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
const loading = ref(false)
const fetchData = async () => {
loading.value = true
error.value = null
try {
const response = await fetch(toValue(url))
data.value = await response.json()
} catch (e) {
error.value = e
} finally {
loading.value = false
}
}
watchEffect(() => {
fetchData()
})
return { data, error, loading }
}
```
**Event Listeners:**
```typescript
export function useEventListener(target, event, callback) {
onMounted(() => target.addEventListener(event, callback))
onUnmounted(() => target.removeEventListener(event, callback))
}
```
**Nested Composables:**
```typescript
export function useMousePosition() {
const x = ref(0)
const y = ref(0)
useEventListener(window, 'mousemove', (event) => {
x.value = event.pageX
y.value = event.pageY
})
return { x, y }
}
```
Provide:
1. The composable function in a separate file (e.g., `composables/useFeatureName.ts`)
2. Usage example in a component
3. TypeScript types if applicable
4. Brief explanation of how it works
5. Any caveats or considerations for the specific use case
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/vue-3-composable-generator/raw