Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.3 KiB
4.3 KiB
title, impact, impactDescription, type, tags
| title | impact | impactDescription | type | tags | |||||
|---|---|---|---|---|---|---|---|---|---|
| Use v-prefix Naming Convention for Local Directives | LOW | Proper naming enables automatic directive recognition in script setup | best-practice |
|
Use v-prefix Naming Convention for Local Directives
Impact: LOW - In <script setup>, any camelCase variable starting with the v prefix can automatically be used as a custom directive. This convention enables seamless local directive registration without explicit configuration.
Following this naming pattern ensures Vue correctly recognizes and registers your local directives.
Task Checklist
- Name local directive variables with
vprefix in camelCase (e.g.,vFocus,vHighlight) - Use the directive in templates without the
vprefix lowercase (e.g.,v-focus,v-highlight) - For multi-word directives, use camelCase in script and kebab-case in template
Incorrect:
<script setup>
// WRONG: No v prefix - won't be recognized as directive
const focus = {
mounted: (el) => el.focus()
}
// WRONG: Wrong casing
const VFocus = {
mounted: (el) => el.focus()
}
// WRONG: Kebab-case in script
const 'v-focus' = { // Syntax error
mounted: (el) => el.focus()
}
</script>
<template>
<!-- These won't work -->
<input focus />
<input v-Focus />
</template>
Correct:
<script setup>
// CORRECT: v prefix with camelCase
const vFocus = {
mounted: (el) => el.focus()
}
const vHighlight = {
mounted: (el) => {
el.classList.add('is-highlight')
}
}
// CORRECT: Multi-word directive
const vClickOutside = {
mounted(el, binding) {
el._handler = (e) => {
if (!el.contains(e.target)) binding.value(e)
}
document.addEventListener('click', el._handler)
},
unmounted(el) {
document.removeEventListener('click', el._handler)
}
}
// CORRECT: Function shorthand with v prefix
const vColor = (el, binding) => {
el.style.color = binding.value
}
</script>
<template>
<!-- Use kebab-case in template -->
<input v-focus />
<p v-highlight>Highlighted text</p>
<div v-click-outside="closeMenu">Dropdown</div>
<span v-color="'red'">Colored text</span>
</template>
Template Casing Rules
In templates, directives should use kebab-case:
<script setup>
const vMyLongDirectiveName = (el) => { /* ... */ }
const vAutoFocusInput = (el) => el.focus()
const vLazyLoadImage = { /* ... */ }
</script>
<template>
<!-- camelCase in script -> kebab-case in template -->
<div v-my-long-directive-name></div>
<input v-auto-focus-input />
<img v-lazy-load-image />
</template>
Options API Registration
Without <script setup>, directives need explicit registration:
// Local registration with Options API
export default {
directives: {
// Key is directive name (without v- prefix)
focus: {
mounted: (el) => el.focus()
},
highlight: {
mounted: (el) => el.classList.add('is-highlight')
},
// Multi-word uses camelCase key
clickOutside: {
mounted(el, binding) { /* ... */ },
unmounted(el) { /* ... */ }
}
}
}
Global Registration
For global directives, register on the app instance:
// main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
// Global directive - name without v- prefix
app.directive('focus', {
mounted: (el) => el.focus()
})
// Multi-word directive
app.directive('click-outside', {
mounted(el, binding) { /* ... */ },
unmounted(el) { /* ... */ }
})
// Function shorthand
app.directive('color', (el, binding) => {
el.style.color = binding.value
})
app.mount('#app')
Importing Directives
When importing directives, rename to add v prefix:
// directives/focus.js
export const focus = {
mounted: (el) => el.focus()
}
// In component
<script setup>
import { focus as vFocus } from '@/directives/focus'
// Now usable as v-focus in template
</script>
// Or export with v prefix already
// directives/focus.js
export const vFocus = {
mounted: (el) => el.focus()
}
// In component
<script setup>
import { vFocus } from '@/directives/focus'
// Directly usable as v-focus
</script>