All skills
onmax avatar

/vue-best-practices

@de09c7b official
by Maxonmax/nuxt-skills715 stars
38

MUST be used for Vue.js tasks. Strongly recommends Composition API with `<script setup>` and TypeScript as the standard approach. Covers Vue 3, SSR, Volar, vue-tsc. Load for any Vue, .vue files, Vue Router, Pinia, or Vite with Vue work. ALWAYS use Composition API unless the project explicitly requires Options API.

Use this Skill: https://skilld.dev/gh/onmax/nuxt-skills/vue-best-practices

This session only. Nothing lands on disk.

referencesdirectives.md

≈953 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Directive Best Practices

Impact: MEDIUM - Directives are for low-level DOM access. Use them sparingly, keep them side-effect safe, and prefer components or composables when you need stateful or reusable UI behavior.

Task List

  • Use directives only when you need direct DOM access
  • Do not mutate directive arguments or binding objects
  • Clean up timers, listeners, and observers in unmounted
  • Register directives in <script setup> with the v- prefix
  • In TypeScript projects, type directive values and augment template directive types
  • Prefer components or composables for complex behavior

Treat Directive Arguments as Read-Only

Directive bindings are not reactive storage. Don’t write to them.

const vFocus = {
  mounted(el, binding) {
    // binding.value is read-only
    el.focus()
  }
}

Avoid Directives on Components

Directives apply to DOM elements. When used on components, they attach to the root element and can break if the root changes.

BAD:

<MyInput v-focus />

GOOD:

<!-- MyInput.vue -->
<script setup>
const vFocus = (el) => el.focus()
</script>

<template>
  <input v-focus />
</template>

Clean Up Side Effects in unmounted

Any timers, listeners, or observers must be removed to avoid leaks.

const vResize = {
  mounted(el) {
    const observer = new ResizeObserver(() => {})
    observer.observe(el)
    el._observer = observer
  },
  unmounted(el) {
    el._observer?.disconnect()
  }
}

Prefer Function Shorthand for Single-Hook Directives

If you only need mounted/updated, use the function form.

const vAutofocus = (el) => el.focus()

Use the v- Prefix and Script Setup Registration

<script setup>
const vFocus = (el) => el.focus()
</script>

<template>
  <input v-focus />
</template>

Type Custom Directives in TypeScript Projects

Use Directive<Element, ValueType> so binding.value is typed, and augment Vue's template types so directives are recognized in SFC templates.

BAD:

// Untyped directive value and no template type augmentation
export const vHighlight = {
  mounted(el, binding) {
    el.style.backgroundColor = binding.value
  }
}

GOOD:

import type { Directive } from 'vue'

type HighlightValue = string

export const vHighlight = {
  mounted(el, binding) {
    el.style.backgroundColor = binding.value
  }
} satisfies Directive<HTMLElement, HighlightValue>

declare module 'vue' {
  interface ComponentCustomProperties {
    vHighlight: typeof vHighlight
  }
}

Handle SSR with getSSRProps

Directive hooks such as mounted and updated do not run during SSR. If a directive sets attributes/classes that affect rendered HTML, provide an SSR equivalent via getSSRProps to avoid hydration mismatches.

BAD:

const vTooltip = {
  mounted(el, binding) {
    el.setAttribute('data-tooltip', binding.value)
    el.classList.add('has-tooltip')
  }
}

GOOD:

const vTooltip = {
  mounted(el, binding) {
    el.setAttribute('data-tooltip', binding.value)
    el.classList.add('has-tooltip')
  },
  getSSRProps(binding) {
    return {
      'data-tooltip': binding.value,
      class: 'has-tooltip'
    }
  }
}

Prefer Declarative Templates When Possible

If a standard attribute or binding works, use it instead of a directive.

Decide Between Directives and Components

Use a directive for DOM-level behavior. Use a component when behavior affects structure, state, or rendering.

Source: SKILL.md on GitHub

No alerts9d3 checks · Risk SAFE
  • Gen Agent Trust Hub9d

    This skill provides a detailed set of best practices for Vue.js development, focusing on performance, state management, and component architecture. It includes security-conscious advice regarding the sanitization of HTML content. A minor security observation is noted regarding the potential for indirect prompt injection when handling untrusted user input, although the skill proactively provides mitigations for this risk.

  • Socket9d

    No alerts

  • Snyk9d

    Risk: LOW · No issues

Signed by skilld at de09c7b. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated last week
metadata
{
  "author": "github.com/vuejs-ai",
  "version": "18.0.0"
}

README badge

README badge for onmax/nuxt-skills/vue-best-practices