Arguments and the Event Object

One function can handle several buttons, when each passes it something different. In @click, call the function with an argument, just as you would in the script:

<script setup>
import { ref } from "vue";

const lastOrder = ref("nothing yet");

function addToOrder(name) {
    lastOrder.value = name;
}
</script>

<template>
    <p>Last order: {{ lastOrder }}</p>
    <button @click="addToOrder('Espresso')">Espresso</button>
    <button @click="addToOrder('Green Tea')">Green Tea</button>
</template>

A click on Espresso shows Last order: Espresso. The name in the attribute is in single quotes, because the attribute itself is in double ones.

In the JavaScript course, this would have been a mistake: button.addEventListener("click", addToOrder("Espresso")) calls the function at once, while the page loads, and gives addEventListener what the function returns. In a Vue template, it's right. Vue doesn't run what's in @click while it renders; it makes a function of it, and runs that on each click. That's also why @click="addCup" and @click="addCup()" both work.

And the event object, which the browser gives handlers? A handler named without parentheses, like @click="addCup", gets it as its argument, as with addEventListener:

<script setup>
function showEvent(event) {
    console.log(event.type);
    console.log(event.target.textContent);
}
</script>

<template>
    <button @click="showEvent">Espresso</button>
</template>

A click prints:

click
Espresso

When you call a function with your own arguments, Vue gives you the event object as $event, in case you need it too: @click="addToOrder('Espresso', $event)". You'll rarely need it for clicks, but in the next exercise, the event object tells you what was typed into a field.

Instructions

  1. Write a function addToOrder(name) that puts the name into lastItem. Give each of the three buttons a click handler that calls it with the item's name, for example addToOrder('Espresso').

  2. Give addToOrder() a second parameter, price, which it adds to total, and pass each button's price to it: addToOrder('Espresso', 2).