963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
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>