Vue apps, data, lists, events, computed values and components, and the same ideas in Preact and Svelte.
Print a cheat sheet (the whole course or one unit, with a picture of what each command draws)
<div id="app">
the page
</div>
<script src="vue.js"></script>
<script>
const { createApp, ref, computed } = Vue;
createApp({
setup() {
data and functions
return { names };
}
}).mount("#app");
</script>
Example
<div id="app">
<p>Today: {{ temp }} °C</p>
</div>
<script src="vue.js"></script>
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const temp = ref(21);
return { temp };
}
}).mount("#app");
</script>
Vue looks after everything inside the div with id app. setup makes the data and functions, and returns the names the page can use. vue.js sits beside the page.

id: vue-app
const score = ref(0);
Data that Vue watches: when it changes, the page follows. Return it from setup. In the script its value is score.value; on the page, just score.
id: ref-data
{{ score }}
Shows a value from setup on the page, and keeps it up to date. Any short expression works: {{ score * 2 }}.
id: show-data
<button @click="addPoint">Add</button>
Runs a function from setup when the button is clicked. A short change works too: @click="score++".
id: click-event
<li v-for="name in players">{{ name }}</li>
Example
<ul id="app">
<li v-for="fruit in fruits">{{ fruit }}</li>
</ul>
<script src="vue.js"></script>
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const fruits = ref(["Apple", "Pear", "Plum"]);
return { fruits };
}
}).mount("#app");
</script>
Makes this tag once for each item in the list. Put it on the tag you want more of (the li, not the ul).

id: v-for
<p v-if="players.length === 0">No players yet.</p>
Shows the tag only while the condition is true. v-else on the next tag shows when it is false.
id: v-if
<input v-model="newName">
Joins a box to a ref, both ways: typing changes the data, and changing the data changes the box. On a tick box it is true or false.
id: v-model
function addPoint() {
score.value++;
}
A function the page can run (return it from setup). In the script, a ref's value is in .value.
id: function-in-setup
const total = computed(() => adults.value * 12);
A value worked out from other data. Vue works it out again whenever that data changes, so it never goes stale. Never set it yourself.
id: computed
app.component("player-card", {
props: ["name"],
template: `<p>{{ name }}</p>`
});
A tag of your own, made once and used many times: <player-card :name="p.name"></player-card>. The colon passes a value. Make the app with const app = createApp(...), add components, then app.mount("#app").
id: component-and-props
<div id="app"></div>
<script src="preact.js"></script>
<script>
const { html, render, useState } = htmPreact;
function App() {
state and functions
return html`the page`;
}
render(html`<${App} />`, document.querySelector("#app"));
</script>
Preact works like React. A component is a function that returns its page, written in html`…` (htm). Preact runs the function again after every change.
id: preact-app
const [stars, setStars] = useState([]);
Preact and React state: the value, and a function to change it. Always give it a new value: setStars([...stars, item]), never stars.push.
id: usestate
<textarea data-svelte hidden>
<script>
state and functions
</script>
the page
</textarea>
<script src="svelte.js"></script>
Example
<textarea data-svelte hidden>
<script>
let name = $state("world");
</script>
<p>Hello, {name}!</p>
</textarea>
<script src="svelte.js"></script>
Here a Svelte component sits in a hidden textarea and svelte.js compiles it in the page. In a real project it is its own file, App.svelte.

id: svelte-component
let count = $state(0);
let double = $derived(count * 2);
Svelte's data that changes, and a value worked out from it. Change $state data directly (count++, list.push). Show it with {count}; choose with {#if …} … {/if}.
id: state-and-derived