Directives
Interpolation (Chapter 2) only handles text content between tags. For everything else — setting an attribute, responding to an event, syncing a form input — Vue uses directives: special v- prefixed attributes, the same conceptual mechanism as Angular's bindings, just with different syntax. These three are the workhorses.
v-bind — Binding an Attribute
v-bind binds an attribute to a reactive expression rather than a static string — :disabled="isSaving" sets the real boolean disabled property from the isSaving ref. The : shorthand is near-universal in real code. This is the exact equivalent of Angular's [disabled]="isSaving" (square brackets) and serves the same purpose as React's disabled={isSaving} — passing a real value, not a string.
v-on — Listening for Events
v-on attaches an event listener — already used informally in earlier chapters via its @ shorthand. @click="increment" is Vue's version of Angular's (click)="increment()" and React's onClick={increment}. Two conveniences: you can write a method name (@click="increment") or an inline expression (@click="count++"), and the native event object is available as $event when you need it (@input="onInput($event)").
@submit.prevent="onSubmit" calls event.preventDefault() for you (no manual call like React's Fundamentals Chapter 4 needed), @click.stop stops propagation, @keyup.enter fires only on the Enter key. These small declarative shortcuts replace boilerplate you'd write by hand in React.
v-model — Two-Way Binding
v-model keeps a form input and a ref synchronized in both directions automatically — typing updates name, and changing name in code updates the input. This is the same end result as Angular's [(ngModel)], and it collapses React's manual controlled-input pattern (value + onChange, Fundamentals Chapter 7) into a single directive. Under the hood it's just :value + @input combined — a shorthand Vue provides, and one you'll build yourself on a custom component in Chapter 7.
v-model on Other Input Types
v-model automatically adapts to the input type — a checkbox binds to a boolean, a <select> binds to the chosen option's value, radio buttons to the selected value, all with the same v-model attribute. This is noticeably less fiddly than React, where a checkbox needed checked/e.target.checked while a text input needed value/e.target.value (Fundamentals Chapter 7) — Vue figures out the right property and event for you.
[(ngModel)] required importing FormsModule into the component, Vue's v-model is built into the template compiler and works out of the box — no import, no setup. One fewer thing to forget.
| Vue | Angular | React |
|---|---|---|
| :attr="x" | [attr]="x" | attr={x} |
| @event="handler" | (event)="handler()" | onEvent={handler} |
| v-model="x" | [(ngModel)]="x" | value={x} onChange={...} |
| @submit.prevent | manual preventDefault() | manual preventDefault() |
Coding Challenges
Build a component with an isLocked ref, a Save button whose disabled attribute is v-bind-bound to it, and a second button (@click) that toggles isLocked. Use the shorthand syntaxes (: and @).
📄 View solutionBuild a single-field form using @submit.prevent on the form and v-model on a text input, logging the value on submit and clearing the input afterward — with no manual preventDefault call.
📄 View solutionBuild a component with a text input, a checkbox, and a select dropdown, each v-model-bound to its own ref (string, boolean, string), displaying all three current values live below the form.
📄 View solutionChapter 3 Quick Reference
- v-bind:attr (shorthand :attr) — bind an attribute to a reactive expression (= Angular
[attr]) - v-on:event (shorthand @event) — listen for an event (= Angular
(event)/ ReactonEvent) - $event — the native event object, passed explicitly when needed
- Modifiers:
@submit.prevent,@click.stop,@keyup.enter— declarative shortcuts - v-model — two-way binding on a form input (= Angular
[(ngModel)]), no import needed v-modelauto-adapts to input type (text/checkbox/select/radio) — simpler than React's per-type handling- Next chapter: conditional and list rendering —
v-ifandv-for