Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/dynamic-argument-constraints.md
1---2title: Dynamic Directive Arguments Have Syntax Constraints3impact: MEDIUM4impactDescription: Invalid dynamic arguments cause silent failures or browser compatibility issues5type: capability6tags: [vue3, template, directives, v-bind, v-on, dynamic-arguments]7---89# Dynamic Directive Arguments Have Syntax Constraints1011**Impact: MEDIUM** - Dynamic directive arguments (e.g., `:[attributeName]`, `@[eventName]`) have value and syntax constraints that can cause silent failures. In-DOM templates also have case sensitivity issues with browsers lowercasing attribute names.1213Dynamic arguments allow runtime determination of which attribute or event to bind, but they have restrictions that differ from static arguments.1415## Task Checklist1617- [ ] Ensure dynamic arguments evaluate to strings or `null`18- [ ] Avoid spaces and quotes inside dynamic argument brackets19- [ ] Use computed properties for complex dynamic argument expressions20- [ ] In in-DOM templates, use lowercase attribute names or switch to SFCs21- [ ] Use `null` to explicitly remove a binding2223**Incorrect:**24```vue25<template>26<!-- ERROR: Spaces and quotes not allowed in dynamic arguments -->27<a :[' foo' + bar]="value">Link</a>28<a :["data-" + name]="value">Link</a>2930<!-- WARNING: Non-string values (except null) trigger warnings -->31<a :[123]="value">Link</a>32<a :[someObject]="value">Link</a>3334<!-- BUG in in-DOM templates: Browsers lowercase attribute names -->35<!-- This becomes :[someattr] which won't match someAttr -->36<a :[someAttr]="url">Link</a>37</template>3839<script setup>40// If component expects someAttr but browser lowercases to someattr41// the binding silently fails42const someAttr = 'href'43</script>44```4546**Correct:**47```vue48<template>49<!-- OK: Simple variable reference -->50<a :[attributeName]="url">Link</a>5152<!-- OK: Use computed property for complex expressions -->53<a :[dynamicAttr]="value">Link</a>5455<!-- OK: null removes the binding -->56<button :[disabledAttr]="isDisabled">Submit</button>5758<!-- OK: Dynamic event names -->59<button @[eventName]="handler">Click</button>6061<!-- OK: In SFCs, case is preserved -->62<a :[someAttr]="url">Link</a>63</template>6465<script setup>66import { ref, computed } from 'vue'6768// Simple string variable69const attributeName = ref('href')70const url = ref('https://vuejs.org')7172// Complex expression via computed property73const prefix = ref('data')74const name = ref('id')75const dynamicAttr = computed(() => `${prefix.value}-${name.value}`)7677// Conditional binding with null78const isDisabled = ref(false)79const disabledAttr = computed(() => isDisabled.value ? 'disabled' : null)8081// Dynamic events82const useTouch = ref(false)83const eventName = computed(() => useTouch.value ? 'touchstart' : 'click')8485function handler() {86console.log('Event triggered')87}88</script>89```9091## In-DOM Template Workaround9293When writing templates directly in HTML (not SFCs), use lowercase:9495```html96<!-- In-DOM template (index.html) -->97<div id="app">98<!-- Use lowercase to avoid browser issues -->99<a :[attrname]="url">Link</a>100</div>101102<script type="module">103import { createApp, ref } from 'vue'104105createApp({106setup() {107// Match the lowercase used in template108const attrname = ref('href')109const url = ref('https://vuejs.org')110return { attrname, url }111}112}).mount('#app')113</script>114```115116## SFC vs In-DOM Templates117118| Feature | SFC (.vue files) | In-DOM (HTML) |119|---------|------------------|---------------|120| Case sensitivity | Preserved | Lowercased by browser |121| Dynamic arguments | Full support | Lowercase only |122| Recommendation | Preferred | Use for progressive enhancement |123124## Valid Dynamic Argument Values125126```vue127<script setup>128// String values - OK129const attr1 = 'href'130const attr2 = 'data-custom'131132// null - OK (removes binding)133const attr3 = null134135// undefined - OK (removes binding)136const attr4 = undefined137138// Numbers, objects, arrays - WARNING139const attr5 = 123 // Warning: should be string140const attr6 = { foo: 1 } // Warning: should be string141</script>142```143144## Reference145- [Vue.js Template Syntax - Dynamic Arguments](https://vuejs.org/guide/essentials/template-syntax.html#dynamic-arguments)146- [Vue.js Template Syntax - Dynamic Argument Value Constraints](https://vuejs.org/guide/essentials/template-syntax.html#dynamic-argument-value-constraints)147