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.

referencetemplate-functions-no-side-effects.md

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

Template Functions Must Be Pure Without Side Effects

Impact: MEDIUM - Functions called in templates execute on every component re-render. Functions with side effects (modifying data, API calls, logging) will cause unpredictable behavior, performance issues, and difficult-to-debug bugs.

Template expressions including function calls are evaluated whenever the component updates. This makes them unsuitable for operations that should only happen once or that modify state.

Task Checklist

  • Keep template functions pure (same input = same output)
  • Never modify reactive state inside template functions
  • Never make API calls or async operations in template functions
  • Move side effects to event handlers, watchers, or lifecycle hooks
  • Use computed properties for derived values instead of functions when possible
  • Avoid expensive computations; use computed properties for caching

Incorrect:

<template>
  <!-- BAD: Modifies state on every render -->
  <p>{{ incrementAndGet() }}</p>

  <!-- BAD: API call on every render -->
  <div>{{ fetchUserName() }}</div>

  <!-- BAD: Logging side effect -->
  <span>{{ logAndFormat(date) }}</span>

  <!-- BAD: Expensive computation without caching -->
  <ul>
    <li v-for="item in filterAndSort(items)" :key="item.id">
      {{ item.name }}
    </li>
  </ul>

  <!-- BAD: Random values change on every render -->
  <p>{{ getRandomGreeting() }}</p>
</template>

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

const count = ref(0)
const items = ref([/* large array */])

// BAD: Has side effect - modifies state
function incrementAndGet() {
  count.value++  // Side effect!
  return count.value
}

// BAD: Async operation in template
async function fetchUserName() {
  const res = await fetch('/api/user')  // Side effect!
  return (await res.json()).name
}

// BAD: Logging is a side effect
function logAndFormat(date) {
  console.log('Formatting date:', date)  // Side effect!
  return new Date(date).toLocaleDateString()
}

// BAD: Expensive, runs every render without caching
function filterAndSort(items) {
  return items
    .filter(i => i.active)
    .sort((a, b) => a.name.localeCompare(b.name))
}

// BAD: Non-deterministic
function getRandomGreeting() {
  const greetings = ['Hello', 'Hi', 'Hey']
  return greetings[Math.floor(Math.random() * greetings.length)]
}
</script>

Correct:

<template>
  <!-- OK: Pure formatting function -->
  <p>Count: {{ count }}</p>
  <button @click="increment">Increment</button>

  <!-- OK: Data fetched via lifecycle/watcher -->
  <div>{{ userName }}</div>

  <!-- OK: Pure function, no side effects -->
  <span>{{ formatDate(date) }}</span>

  <!-- OK: Computed property caches result -->
  <ul>
    <li v-for="item in filteredAndSortedItems" :key="item.id">
      {{ item.name }}
    </li>
  </ul>

  <!-- OK: Random value set once -->
  <p>{{ greeting }}</p>
</template>

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

const count = ref(0)
const userName = ref('')
const date = ref(new Date())
const items = ref([/* large array */])

// Side effects in event handlers
function increment() {
  count.value++
}

// Fetch data in lifecycle hook
onMounted(async () => {
  const res = await fetch('/api/user')
  userName.value = (await res.json()).name
})

// Pure function - same input, same output
function formatDate(date) {
  return new Date(date).toLocaleDateString()
}

// Computed property - cached, only recalculates when dependencies change
const filteredAndSortedItems = computed(() => {
  return items.value
    .filter(i => i.active)
    .sort((a, b) => a.name.localeCompare(b.name))
})

// Set random value once, not on every render
const greetings = ['Hello', 'Hi', 'Hey']
const greeting = ref(greetings[Math.floor(Math.random() * greetings.length)])
</script>

Pure Function Guidelines

A pure function:

  1. Given the same inputs, always returns the same output
  2. Does not modify any external state
  3. Does not perform I/O operations (network, console, file system)
  4. Does not depend on mutable external state
// PURE - safe for templates
function formatCurrency(amount, currency = 'USD') {
  return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount)
}

function fullName(first, last) {
  return `${first} ${last}`
}

function isExpired(date) {
  return new Date(date) < new Date()
}

// IMPURE - unsafe for templates
function logAndReturn(value) {
  console.log(value)  // I/O
  return value
}

function getFromLocalStorage(key) {
  return localStorage.getItem(key)  // External state
}

function updateAndReturn(obj, key, value) {
  obj[key] = value  // Mutation
  return obj
}

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.