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.

referencesrender-functions.md

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

Render Function Patterns and Performance

Impact: MEDIUM - Render functions are powerful but opt out of template compiler optimizations. Use them intentionally and apply the key patterns below to keep output correct and performant.

Task List

  • Prefer templates; use render functions only when templates cannot express the logic
  • Always add stable keys when rendering lists with h()/JSX
  • Use withModifiers / withKeys for event modifiers
  • Implement v-model via modelValue + onUpdate:modelValue
  • Apply custom directives with withDirectives
  • Use functional components for stateless presentational UI

Prefer templates over render functions

BAD:

<script setup>
import { h, ref } from 'vue'

const count = ref(0)
const render = () => h('div', `Count: ${count.value}`)
</script>

GOOD:

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <div>Count: {{ count }}</div>
</template>

Always add keys for list rendering

BAD:

import { h, ref } from 'vue'

export default {
  setup() {
    const items = ref([{ id: 1, name: 'Apple' }])

    return () => h('ul',
      items.value.map(item => h('li', item.name))
    )
  }
}

GOOD:

import { h, ref } from 'vue'

export default {
  setup() {
    const items = ref([{ id: 1, name: 'Apple' }])

    return () => h('ul',
      items.value.map(item => h('li', { key: item.id }, item.name))
    )
  }
}

Use withModifiers / withKeys for event modifiers

BAD:

import { h } from 'vue'

export default {
  setup() {
    const handleClick = (e) => {
      e.stopPropagation()
      e.preventDefault()
    }

    return () => h('button', { onClick: handleClick }, 'Click')
  }
}

GOOD:

import { h, withModifiers, withKeys } from 'vue'

export default {
  setup() {
    const handleClick = () => {}
    const handleEnter = () => {}

    return () => h('div', [
      h('button', {
        onClick: withModifiers(handleClick, ['stop', 'prevent'])
      }, 'Click'),
      h('input', {
        onKeyup: withKeys(handleEnter, ['enter'])
      })
    ])
  }
}

Implement v-model explicitly

BAD:

import { h, ref } from 'vue'
import CustomInput from './CustomInput.vue'

export default {
  setup() {
    const text = ref('')
    return () => h(CustomInput, { modelValue: text.value })
  }
}

GOOD:

import { h, ref } from 'vue'
import CustomInput from './CustomInput.vue'

export default {
  setup() {
    const text = ref('')
    return () => h(CustomInput, {
      modelValue: text.value,
      'onUpdate:modelValue': (value) => { text.value = value }
    })
  }
}

Use withDirectives for custom directives

BAD:

import { h } from 'vue'

const vFocus = { mounted: (el) => el.focus() }

export default {
  setup() {
    return () => h('input', { 'v-focus': true })
  }
}

GOOD:

import { h, withDirectives } from 'vue'

const vFocus = { mounted: (el) => el.focus() }

export default {
  setup() {
    return () => withDirectives(h('input'), [[vFocus]])
  }
}

Prefer functional components for stateless UI

BAD:

import { h } from 'vue'

export default {
  setup() {
    return () => h('span', { class: 'badge' }, 'New')
  }
}

GOOD:

import { h } from 'vue'

function Badge(props, { slots }) {
  return h('span', { class: 'badge' }, slots.default?.())
}

Badge.props = ['variant']

export default Badge

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