Chapter 4: Vue v-bind
Vue-bind directive in Vue 3 (the one you’re most likely using in 2026). This is probably the single most-used directive after v-on (@click) and v-for. Once you master v-bind, your templates start feeling truly dynamic.
Think of v-bind as the way Vue says: “Hey browser, don’t hard-code this attribute — keep it in sync with my JavaScript data reactively.”
Without v-bind, you can’t put dynamic values inside HTML attributes (because {{ }} doesn’t work there).
1. Basic Purpose & Syntax
v-bind dynamically binds one or more attributes (or props on components) to a JavaScript expression.
Full syntax:
|
0 1 2 3 4 5 6 |
<tag v-bind:attribute-name="expression"></tag> |
Super-common shorthand (you’ll see this 95% of the time):
|
0 1 2 3 4 5 6 |
<tag :attribute-name="expression"></tag> |
The : is just sugar for v-bind: — invented because v-bind is used so often.
2. Simple Example – Binding src, alt, href, id, etc.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<!-- ProductCard.vue --> <template> <div class="card"> <!-- Dynamic image source --> <img :src="product.image" :alt="product.name + ' photo'" /> <!-- Dynamic link --> <a :href="product.url" target="_blank"> View on Amazon → {{ product.name }} </a> <!-- Dynamic id & data attribute --> <button :id="'buy-' + product.id" :data-price="product.price"> Buy for ₹{{ product.price }} </button> </div> </template> <script setup> import { ref } from 'vue' const product = ref({ id: 101, name: 'Vue.js Mug', image: 'https://example.com/vue-mug.jpg', url: 'https://amzn.in/vue-mug', price: 499 }) </script> |
→ Whenever product.image changes → image src updates automatically No document.getElementById().src = … needed!
3. The Star Feature: :class & :style Bindings
Vue gives special superpowers to v-bind when used on class and style.
A. Object syntax for :class (most common & readable)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<template> <div class="base-card" :class="{ 'is-active': isActive, 'is-error': hasError, 'text-red-600': hasError }" > Status message </div> <button @click="toggleActive">Toggle Active</button> </template> <script setup> import { ref } from 'vue' const isActive = ref(false) const hasError = ref(true) function toggleActive() { isActive.value = !isActive.value } </script> <style> .base-card { padding: 1rem; border: 1px solid gray; } .is-active { border-color: blue; background: #eff6ff; } .is-error { border-color: red; } .text-red-600 { color: #dc2626; } </style> |
How it works:
- Key = class name you want
- Value = truthy/falsy expression → if truthy → class added, else removed
B. Array syntax for :class (when mixing static + conditional)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<div :class="[ 'font-bold', isLarge ? 'text-2xl' : 'text-base', { 'bg-green-100': success, 'bg-red-100': error } ]"> Message </div> |
C. :style – object or array
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<div :style="{ color: textColor, fontSize: fontSize + 'px', 'background-color': bg }"> Styled paragraph </div> <!-- Array of style objects --> <div :style="[baseStyles, overrideStyles]"> |
|
0 1 2 3 4 5 6 7 8 9 10 |
const textColor = ref('navy') const fontSize = ref(20) const bg = ref('#fef3c7') const baseStyles = { margin: '1rem', padding: '1rem' } const overrideStyles = ref({ border: '2px dashed orange' }) |
4. Binding Multiple Attributes at Once (Object Syntax)
Super useful for passing many attrs or spreading props.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<div v-bind="{ id: 'section-' + sectionId, 'data-type': type, role: 'region', 'aria-label': label }"> Content </div> <!-- Or shorthand --> <div v-bind="allAttrs"></div> |
|
0 1 2 3 4 5 6 7 8 9 10 |
const allAttrs = reactive({ id: 'main', tabindex: 0, 'data-test': 'hero' }) |
5. Same-Name Shorthand (New in Vue 3.4+ – 2026 favorite!)
If the attribute name and variable name are the same → you can skip the value!
|
0 1 2 3 4 5 6 7 8 9 10 |
<!-- Before 3.4 --> <img :src="src" :alt="alt" :width="width"> <!-- Vue 3.4+ magic --> <img :src :alt :width> |
Equivalent to :src=”src” etc. — clean!
6. Dynamic Attribute Name (computed or variable)
|
0 1 2 3 4 5 6 |
<button :[attrName]="isDisabled">Click</button> |
|
0 1 2 3 4 5 6 7 |
const attrName = ref('disabled') const isDisabled = ref(true) |
→ Becomes <button disabled>…</button>
7. Binding to Component Props
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!-- Parent --> <UserCard :user="currentUser" :is-premium="true" /> <!-- Child UserCard.vue --> <script setup> defineProps({ user: Object, isPremium: Boolean }) </script> |
:user is shorthand for v-bind:user=”currentUser”
8. Modifiers (less common but good to know)
- .camel → converts kebab-case to camelCase (mostly for SVG/certain attrs)
|
0 1 2 3 4 5 6 7 |
<svg :view-box.camel="viewBox"></svg> <!-- becomes viewBox --> |
- .prop (Vue 3.2+) → force DOM property instead of attribute
|
0 1 2 3 4 5 6 7 |
<input :value.prop="textValue"> <!-- sets input.value directly (not value attribute) --> |
- .attr → opposite, force attribute
Quick Cheat Sheet Table
| Use Case | Syntax Example | Notes / When to Use |
|---|---|---|
| Normal attribute | :src=”imageUrl” | Images, links, ids |
| Class (object) | :class=”{ active: isActive }” | Toggling classes |
| Class (array) | :class=”[base, { active: flag }]” | Mix static + cond. |
| Style object | :style=”{ color: ‘red’, fontSize: size }” | Inline styles |
| Multiple attrs | v-bind=”{ id, role, ‘data-*’: val }” | Spreading attrs |
| Same-name shorthand (3.4+) | :disabled :readonly | Cleaner code |
| Dynamic attr name | :[attr]=”val” | Rare, advanced |
| Component prop | :user=”userData” | Passing data down |
Pro Tips from 2026 Hyderabad Dev Scene
- Prefer :class object syntax — easiest to read & maintain
- Avoid string concatenation for classes (‘btn ‘ + type) → use object/array instead
- Use Tailwind? :class works perfectly with it: :class=”{ ‘bg-blue-600’: active, ‘bg-gray-200’: !active }”
- Performance: Vue is smart — it only updates changed classes/styles
Want practice? Try building:
- A theme toggle button that changes :class on <body>
- A product grid with conditional “sold out” badge using object class binding
Any part confusing? Want full mini-component example (like pricing card with dynamic styles)? Or difference between :class vs class + ternary?
Just shout — we’ll go deeper 🚀
Keep coding strong! 💙
