Text Interpolation
Shelf's header should say "Reading 2 of 5 books", and the numbers must change the moment a book is added or finished. You never want to find the header element and rewrite its text by hand. In a Vue template you write the sentence once, with holes for the values, and Vue keeps it true.
The rule
Double braces hold one expression; Vue prints it as safe text.
The double curly braces, often called "mustaches", evaluate what is inside and print the result:
<script setup>
import { ref } from 'vue'
const books = ref([
{ title: 'Dune', pages: 412, read: true },
{ title: 'Circe', pages: 393, read: false }
])
const user = ref('Asha')
</script>
<template>
<h1>{{ user }}'s Shelf</h1>
<p>{{ books.length }} books, {{ books[0].title.toUpperCase() }} first</p>
<p>Status: {{ books[1].read ? 'Finished' : 'Reading' }}</p>
</template>Each part of the rule matters:
- One expression. Anything that produces a value works: a variable, arithmetic, a method call, a ternary. Statements do not:
{{ if (read) {...} }}or{{ const x = 1 }}is a compile error. Use a ternary to choose between values. - Printed as text. If
userheld<b>Asha</b>, the page would show the angle brackets literally. Vue escapes the value, which is what keeps user-typed data from turning into markup. - Kept up to date. When
userorbookschanges, Vue re-renders just the text that depends on it.
Refs are unwrapped automatically: write {{ user }}, not {{ user.value }}.
v-text is the directive form of the same idea: <span v-text="user"></span> sets the element's whole text content to user. The braces are more common because they can sit in the middle of a sentence.
One limit: braces work only in text, never inside attribute values. <img src="{{ cover }}"> does not work; attributes need v-bind, the topic of a later lesson.
The shortcut
Before writing braces, ask: "Could this sit on the right of const x = ...?" If yes, it is an expression and it fits. If no, it is a statement and it does not.
Say it in words
"Reading 2 of 5 books", where 2 is the unread count and 5 is the total.
Drills
Answer fast — trust the rule.
Which of these is valid inside {{ }}?
A ref note holds the text <i>great</i>. What does {{ note }} show?
How do you print a ref named user in a template?
Why does <img src="{{ book.cover }}"> fail to show the cover?
Remember
{{ }}takes exactly one expression and prints it as escaped, reactive text.- Shortcut: "could it follow
const x =?" If so, it fits in the braces. - Trap: statements in braces, and braces inside attributes.
