All skills
hyf0 avatar

/vue-options-api-best-practices

@bc922e4 official
by hyf0hyf0/vue-skills2.9k stars
167

Vue 3 Options API style (data(), methods, this context). Each reference shows Options API solution only.

Use this Skill: https://skilld.dev/gh/hyf0/vue-skills/vue-options-api-best-practices

This session only. Nothing lands on disk.

referencets-options-api-proptype-complex-types.md

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

Use PropType for Complex Prop Types in Options API

Impact: MEDIUM - Vue's runtime props option only supports basic constructor functions (String, Number, etc.). To type complex props like interfaces, function signatures, or union types, you must use Vue's PropType utility type.

Task Checklist

  • Import PropType from 'vue' for complex prop types
  • Use as PropType<YourType> after Object, Array, or Function
  • Define interfaces for your complex types
  • Remember: PropType is purely for TypeScript - runtime validation only checks the constructor

The Problem

Vue's runtime prop system uses JavaScript constructor functions, which can't express complex TypeScript types:

// What runtime props support:
props: {
  name: String,       // OK: string
  count: Number,      // OK: number
  enabled: Boolean,   // OK: boolean
  items: Array,       // Problem: any[]
  config: Object,     // Problem: Record<string, any>
  handler: Function   // Problem: (...args: any[]) => any
}

Using PropType for Complex Types

Import and use PropType:

import { defineComponent, PropType } from 'vue'
// or
import type { PropType } from 'vue'

interface User {
  id: number
  name: string
  email: string
}

interface Config {
  theme: 'light' | 'dark'
  maxItems: number
}

export default defineComponent({
  props: {
    // Object with interface
    user: {
      type: Object as PropType<User>,
      required: true
    },

    // Array of typed items
    users: {
      type: Array as PropType<User[]>,
      default: () => []
    },

    // Object with union type
    config: {
      type: Object as PropType<Config>,
      default: () => ({ theme: 'light', maxItems: 10 })
    },

    // Typed function
    onSubmit: {
      type: Function as PropType<(data: User) => Promise<void>>,
      required: true
    },

    // Union of primitives
    id: {
      type: [String, Number] as PropType<string | number>,
      required: true
    },

    // Literal union type
    status: {
      type: String as PropType<'pending' | 'active' | 'completed'>,
      default: 'pending'
    }
  },

  methods: {
    async handleSubmit() {
      // Full type inference!
      await this.onSubmit(this.user)  // onSubmit is properly typed
      console.log(this.user.email)    // user.email is string
      console.log(this.config.theme)  // theme is 'light' | 'dark'
    }
  }
})

Important: Runtime vs Compile-Time

PropType only affects TypeScript compilation. At runtime, Vue still only validates using the constructor:

props: {
  user: {
    type: Object as PropType<User>,
    required: true
  }
}

// Runtime: Vue only checks typeof value === 'object'
// It does NOT validate { id, name, email } structure

// To add runtime validation, use validator:
props: {
  user: {
    type: Object as PropType<User>,
    required: true,
    validator: (user: User) => {
      return typeof user.id === 'number' &&
             typeof user.name === 'string' &&
             typeof user.email === 'string'
    }
  }
}

Common PropType Patterns

Nullable Props

props: {
  // Optional object that can be null
  selectedItem: {
    type: Object as PropType<Item | null>,
    default: null
  }
}

Enum-like Props

type ButtonVariant = 'primary' | 'secondary' | 'danger'

props: {
  variant: {
    type: String as PropType<ButtonVariant>,
    default: 'primary',
    validator: (v: ButtonVariant) =>
      ['primary', 'secondary', 'danger'].includes(v)
  }
}

Generic-like Props with Multiple Types

props: {
  // Accept string, number, or object with id
  value: {
    type: [String, Number, Object] as PropType<string | number | { id: string }>,
    required: true
  }
}

Event Handler Props

interface ClickEventData {
  item: Item
  index: number
}

props: {
  onClick: {
    type: Function as PropType<(data: ClickEventData) => void>,
    required: false
  }
}

Why Not Just Use as?

You might think to skip PropType:

// WRONG - doesn't work as expected
props: {
  user: Object as User  // TypeScript error or incorrect inference
}

// CORRECT - use PropType
props: {
  user: Object as PropType<User>
}

PropType<T> is specifically designed to work with Vue's prop type system.

Reference

Source: SKILL.md on GitHub

No alerts17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    The skill provides comprehensive best practices and TypeScript integration guidelines for the Vue.js Options API. It contains educational content and code examples that are safe and consistent with official Vue.js documentation. No security issues were detected.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    11 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

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

Last checked against GitHub 2 months ago.

Steadyupdated 8 months ago
version
2.0.0
author
github.com/vuejs-ai
  • Vue
  • TypeScript
  • options-api
  • best-practices
  • lifecycle-hooks
  • prop-types
  • type-safety

README badge

README badge for hyf0/vue-skills/vue-options-api-best-practices

Teaches Vue 3 Options API patterns, TypeScript integration, and common mistakes like arrow functions in methods and lifecycle hooks. Covers prop typing, event handler safety, provide/inject limitations, and computed property type inference specific to the Options API style.

Generated from the current SKILL.md.

Does this skill cover Composition API?
No. This skill focuses exclusively on Options API patterns and does not include Composition API examples or guidance.
What TypeScript support does this provide?
The skill includes references for enabling type inference with defineComponent, typing event handlers, complex prop types, provide/inject limitations, and computed property return types in the Options API context.
Does this address method binding issues?
Yes. The skill covers arrow function pitfalls in methods and lifecycle hooks, which commonly break this context binding in the Options API.

Generated from the current SKILL.md. These answers refresh after source changes.