Students predict that v-model follows each letter, add names with a function, match the parts, find score++ on a ref, add a Reset function and a second box, and make a badge maker.
Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.
Predict and Run 10 min · Investigate 15 min · Modify 15 min · Make 15 min
Read the unit primer first. Two new pieces. @click="addPlayer" names a function to run on a click; the function is written in setup and returned with the data. v-model="newName" joins a box to a ref both ways: typing changes the ref, and setting the ref (to empty text, say) changes the box. Compare the DOM course, where students read box.value and listened for the "input" event themselves.
The hard part of the whole course: a ref is a box. On the page Vue opens it for you ({{ score }}, @click="score++"); in the script you open it yourself (score.value++). Writing score++ in a function gives a red error, "Assignment to constant variable", because the ref was made with const. The playground's hint names .value for this case. Expect it all lesson; it is also the planted bug.
Students mix up when to write .value. Ask "are you on the page or in the script?" every time, and let them answer before they type.
| What you will see | A question to ask | The fix |
|---|---|---|
| A red error: Assignment to constant variable. | Is that a ref, changed in the script? | Change its .value: score.value++. |
| Clicking does nothing; the console warns a property is not defined. | Is the function in the return? | return { players, newName, addPlayer, reset }; |
| The box and the paragraph do not match. | Does v-model name the same ref the paragraph shows? | Use the same name in v-model and in {{ }}. |
One possible solution for each task. Other correct programs are fine.
<div id="app">
<h1>Chess team</h1>
<input v-model="newName" placeholder="A name">
<button @click="addPlayer">Add</button>
<button @click="reset">Reset</button>
<p>Adding: {{ newName }}</p>
<ul>
<li v-for="name in players">{{ name }}</li>
</ul>
</div>
<script src="vue.js"></script>
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const players = ref(["Ada", "Sam"]);
const newName = ref("");
function addPlayer() {
if (newName.value !== "") {
players.value.push(newName.value);
newName.value = "";
}
}
function reset() {
players.value = ["Ada", "Sam"];
newName.value = "";
}
return { players, newName, addPlayer, reset };
}
}).mount("#app");
</script>
<div id="app">
<h1>{{ club }} team</h1>
<input v-model="club" placeholder="Club name">
<input v-model="newName" placeholder="A name">
<button @click="addPlayer">Add</button>
<p>Adding: {{ newName }}</p>
<ul>
<li v-for="name in players">{{ name }}</li>
</ul>
</div>
<script src="vue.js"></script>
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const club = ref("Chess");
const players = ref(["Ada", "Sam"]);
const newName = ref("");
function addPlayer() {
if (newName.value !== "") {
players.value.push(newName.value);
newName.value = "";
}
}
return { club, players, newName, addPlayer };
}
}).mount("#app");
</script>
<div id="app">
<h1>Badge maker</h1>
<input v-model="person" placeholder="Your name">
<input v-model="role" placeholder="Your role">
<button @click="shout">Make it loud</button>
<div style="border: 3px solid teal; padding: 12px; margin-top: 12px;">
<h2>{{ person }}</h2>
<p>{{ role }}</p>
</div>
</div>
<script src="vue.js"></script>
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const person = ref("Ada");
const role = ref("Captain");
function shout() {
person.value = person.value.toUpperCase() + "!";
}
return { person, role, shout };
}
}).mount("#app");
</script>
Stretch: Add when Enter is pressed: @keyup.enter="addPlayer" on the box. Remove a player when their name is clicked (pass the name to a function).
Support: Give the Reset function written out; students return it and add the button.
In a Vue function, how do you add 1 to a ref called score, and why is it different on the page?
score.value++; the page unwraps refs for you, but the script reaches the value inside with .value.
Next lesson: computed values, worked out from data and kept up to date. Class idea: find an Add button on a real site and say which data it changes.