Vue Events and Forms
Vue handles user actions with v-on and connects form inputs to your data with v-model.
Listening to Events with v-on
v-on:click runs code when an element is clicked. The short form is @click.
Example
<script setup>
import { ref } from "vue";
const cart = ref(0);
function addToCart() {
cart.value++;
}
</script>
<template>
<p>Items in cart: {{ cart }}</p>
<button v-on:click="addToCart">Add (long form)</button>
<button @click="addToCart">Add (short form)</button>
<button @click="cart = 0">Empty cart</button>
</template>You can give @click a function name, a call with arguments, or a short statement.
Passing Arguments and the Event
Example
<script setup>
function choose(size, event) {
console.log("Size:", size, "Button text:", event.target.textContent);
}
</script>
<template>
<button @click="choose('M', $event)">Medium</button>
</template>Size: M Button text: Medium
$event is a special variable that holds the browser's event object.
Common Events
| Vue | Fires when |
|---|---|
@click | The element is clicked |
@input | The value of an input changes |
@change | A select, checkbox or input is changed and committed |
@submit | A form is submitted |
@keyup | A key is released |
@mouseover | The mouse moves onto the element |
Event Modifiers
Modifiers are small words after a dot that handle common needs for you.
Example
<form @submit.prevent="save">...</form>
<input @keyup.enter="search" placeholder="Press Enter to search" />
<button @click.once="claimGift">Claim free gift</button>| Modifier | What it does |
|---|---|
.prevent | Calls event.preventDefault() (stops page reload on submit) |
.stop | Stops the event from reaching parent elements |
.once | Runs the handler only the first time |
.enter, .esc | Runs only for that key |
Two-Way Binding with v-model
v-model connects an input to a ref. When the user types, the ref changes. When the ref changes, the input changes.
Example
<script setup>
import { ref } from "vue";
const name = ref("");
</script>
<template>
<input v-model="name" placeholder="Your name" />
<p>Hello, {{ name || "guest" }}!</p>
</template>(typing "Hamza") Hello, Hamza!
v-model with Different Inputs
Example
<script setup>
import { ref } from "vue";
const course = ref("web");
const agree = ref(false);
const timing = ref("evening");
const age = ref(18);
const note = ref("");
</script>
<template>
<select v-model="course">
<option value="web">Web Development</option>
<option value="ai">Artificial Intelligence</option>
</select>
<label><input type="checkbox" v-model="agree" /> I agree</label>
<label><input type="radio" value="morning" v-model="timing" /> Morning</label>
<label><input type="radio" value="evening" v-model="timing" /> Evening</label>
<input type="number" v-model.number="age" />
<textarea v-model.trim="note"></textarea>
<p>{{ course }}, {{ timing }}, age {{ age }}, agreed: {{ agree }}</p>
</template>web, evening, age 18, agreed: false
The .number modifier turns the value into a number, and .trim removes spaces at the start and end.
A Complete Form
Example
<script setup>
import { ref } from "vue";
const email = ref("");
const message = ref("");
function subscribe() {
if (!email.value.includes("@")) {
message.value = "Please enter a valid email.";
return;
}
message.value = `Thanks! Updates will go to ${email.value}.`;
email.value = "";
}
</script>
<template>
<form @submit.prevent="subscribe">
<input v-model.trim="email" type="email" placeholder="Email" />
<button>Subscribe</button>
</form>
<p v-if="message">{{ message }}</p>
</template>v-model is a shortcut for :value plus @input. Knowing this helps you understand how it works with your own components later.
Exercise
Exercise
Which line stops a form from reloading the page when it is submitted?
