All skills
hyf0 avatar

/vue-debug-guides

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

Vue 3 debugging and error handling for runtime errors, warnings, async failures, and SSR/hydration issues. Use when diagnosing or fixing Vue issues.

Use this Skill: https://skilld.dev/gh/hyf0/vue-skills/vue-debug-guides

This session only. Nothing lands on disk.

referencedefine-model-default-value-sync.md

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

defineModel Default Value Can Cause Parent-Child Desync

Impact: HIGH - When using defineModel() with a default value and the parent doesn't provide a value, the parent and child components will have different values. The parent's ref stays undefined while the child uses the default, breaking the two-way binding contract.

This subtle bug can cause confusing behavior where the parent component shows one value while the child shows another, and updates may not propagate correctly.

Task Checklist

  • Always provide initial values from the parent when using v-model
  • Don't rely on defineModel defaults as the primary source of truth
  • If defaults are needed, also set them in the parent component
  • Test components with and without v-model props provided

Problem - Parent and child out of sync:

<!-- ChildComponent.vue -->
<script setup>
// Default value of 1 if parent doesn't provide value
const model = defineModel({ default: 1 })
</script>

<template>
  <input v-model="model" type="number">
  <!-- Shows: 1 (from default) -->
</template>
<!-- ParentComponent.vue -->
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

// PROBLEM: Parent ref is undefined, not synced with child's default
const myValue = ref()  // undefined
</script>

<template>
  <ChildComponent v-model="myValue" />

  <!-- DESYNC: Child shows 1, but parent shows undefined -->
  <p>Parent value: {{ myValue }}</p>  <!-- Shows: undefined -->

  <!-- Even after child changes value, parent may not update correctly -->
</template>

Solution 1 - Always provide initial value from parent:

<!-- ParentComponent.vue -->
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

// CORRECT: Parent provides the initial value
const myValue = ref(1)  // Match the expected default
</script>

<template>
  <ChildComponent v-model="myValue" />
  <p>Parent value: {{ myValue }}</p>  <!-- Shows: 1, stays in sync -->
</template>

Solution 2 - Child emits default on mount (if parent control not possible):

<!-- ChildComponent.vue -->
<script setup>
import { onMounted } from 'vue'

const model = defineModel({ default: 1 })

// Sync default value back to parent on mount
onMounted(() => {
  if (model.value === 1) {  // Is using default
    // Force emit to sync parent
    model.value = 1
  }
})
</script>

<template>
  <input v-model="model" type="number">
</template>

Solution 3 - Use required prop or explicit undefined handling:

<!-- ChildComponent.vue -->
<script setup>
import { computed } from 'vue'

// Mark as required - TypeScript will warn if not provided
const model = defineModel({ required: true })

// Or handle undefined explicitly
const safeModel = computed({
  get: () => model.value ?? 1,  // Provide fallback
  set: (val) => { model.value = val }
})
</script>

<template>
  <input v-model="safeModel" type="number">
</template>

Best Practice - Document expected initial values:

<!-- ChildComponent.vue -->
<script setup>
/**
 * @prop modelValue - The numeric value (parent should initialize to 1 or desired default)
 */
const model = defineModel({
  type: Number,
  default: 1,
  // Adding validator helps catch issues in development
  validator: (value) => {
    if (value === undefined) {
      console.warn('ChildComponent: v-model value is undefined. Provide initial value from parent.')
    }
    return true
  }
})
</script>

Reference

Source: SKILL.md on GitHub

No alerts17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill is a comprehensive collection of educational debugging guides and best practices for Vue 3 developers. It contains no executable code or malicious instructions and focuses solely on diagnosing common runtime errors and performance issues.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    140 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at a5fc891. 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

README badge

README badge for hyf0/vue-skills/vue-debug-guides

Guides for diagnosing and fixing Vue 3 runtime errors, reactivity bugs, async failures, and hydration issues across components, templates, watchers, forms, and lifecycle hooks. Covers specific failure modes like stale watchers, ref unwrapping edge cases, v-model sync problems, and SSR mismatches with concrete reference links for each issue.

Generated from the current SKILL.md.

Does this skill cover Vue 2?
No. This skill is specific to Vue 3 debugging and error handling.
What should I use for Vue development best practices instead of debugging?
The skill references a separate `vue-best-practices` skill for development best practices and common gotchas.
Does this cover SSR and hydration issues?
Yes. The skill includes guides for diagnosing and fixing SSR rendering differences and hydration bugs.
Can this help with async watcher and watchEffect problems?
Yes. The skill covers async operation stale data, dependency tracking after await, and proper flush timing for watchers.
Does this address v-model and form-related issues?
Yes. The skill includes guides for v-model initial values, textarea interpolation, IME composition, and custom checkbox form submission.

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