v-bind and v-on
Directives are special attributes that begin with v-. They give Vue’s template engine instructions: bind this value, listen for this event, show this element conditionally. v-bind and v-on are the two you’ll use on nearly every component.
v-bind — dynamic attributes
Section titled “v-bind — dynamic attributes”v-bind binds a DOM attribute or component prop to a JavaScript expression:
<script setup lang="ts">const src = '/avatar.png'const alt = 'Alice profile photo'const isDisabled = true</script>
<template> <img v-bind:src="src" v-bind:alt="alt" /> <button v-bind:disabled="isDisabled">Submit</button></template>The shorthand : is used everywhere in practice:
<img :src="src" :alt="alt" /><button :disabled="isDisabled">Submit</button>Any HTML attribute can be dynamically bound: href, class, style, type, value, title, aria-*, custom data attributes, and Vue component props.
v-on — event listeners
Section titled “v-on — event listeners”v-on attaches an event listener:
<template> <button v-on:click="handleClick">Click me</button> <input v-on:input="handleInput" /> <form v-on:submit="handleSubmit">...</form></template>The shorthand @ is used everywhere:
<button @click="handleClick">Click me</button><input @input="handleInput" /><form @submit="handleSubmit">...</form>Inline handlers
Section titled “Inline handlers”For short operations, skip the function and write the expression inline:
<button @click="count++">+1</button><button @click="name = 'Bob'">Change name</button><button @click="store.deletePerson(id)">Delete</button>Inline handlers receive the native Event object as $event if you need it:
<input @input="query = $event.target.value" />Event modifiers
Section titled “Event modifiers”Vue provides modifiers that chain to event listeners to handle common patterns:
<!-- prevent default (e.g., stop form from reloading the page) --><form @submit.prevent="handleSubmit">...</form>
<!-- stop event propagation --><div @click.stop="handleClick">...</div>
<!-- only fire for exact key --><input @keyup.enter="search" /><input @keyup.escape="clearSearch" />
<!-- only fire once --><button @click.once="init">Initialize</button>These are cleaner than calling event.preventDefault() inside every handler.
Passing arguments to handlers
Section titled “Passing arguments to handlers”<script setup lang="ts">function focusOn(id: string) { store.setFocus(id)}</script>
<template> <PersonCard v-for="person in people" :key="person.id" :name="person.name" @click="focusOn(person.id)" /></template>Exercise
Section titled “Exercise”- Create a button that toggles a
isVisibleref betweentrueandfalseusing an inline@clickhandler. - Bind
:classto show'active'whenisVisibleistrue(just use a ternary for now). - Create a form with a
@submit.preventhandler that logs “Form submitted!” without reloading the page. - Add an input with
@keyup.enterthat logs the input’s current value.
v-bind:attr="value"/:attr="value"binds a dynamic value to an HTML attribute or component prop.v-on:event="handler"/@event="handler"attaches an event listener.- Inline handlers work for simple expressions; function references work for anything complex.
- Event modifiers like
.prevent,.stop,.once, and.enterhandle common patterns cleanly.