Template syntax
A template is the markup inside the <template> block. It is plain HTML into which Vue inserts data from the script. Inserting a value into text is called interpolation.
Interpolation
A variable's value is printed in double curly braces:
<!-- src/App.vue -->
<script setup>
const owner = 'Oleg'
const total = 5
</script>
<template>
<h1>Tasks: {{ owner }}</h1>
<p>Total tasks: {{ total }}</p>
</template>The page shows the lines "Tasks: Oleg" and "Total tasks: 5". If the variable changes, Vue updates the text — how to make a variable changeable is shown in the lesson about ref.
Expressions
Inside the braces you can write any JavaScript expression — anything that produces a value:
<script setup>
const total = 5
const done = 2
const owner = 'Oleg'
</script>
<template>
<p>Left: {{ total - done }}</p>
<p>{{ done === total ? 'All done' : 'Work to do' }}</p>
<p>{{ owner.toUpperCase() }}</p>
</template>The page shows "Left: 3", "Work to do" and "OLEG". Statements such as if, for or a const declaration are not allowed inside the braces — only expressions.
Attributes: v-bind
Double braces do not work in attributes. To put a value into an attribute, prefix it with v-bind: or the short form — a colon:
<script setup>
const logo = '/favicon.ico'
const hint = 'Task list'
</script>
<template>
<img v-bind:src="logo" alt="Logo">
<h1 :title="hint">My tasks</h1>
</template>The image gets src set to /favicon.ico, and the heading gets a tooltip "Task list". The quoted value after the colon is also a JavaScript expression, not a string.
| Syntax | Attribute value |
|---|---|
title="hint" | The string hint |
:title="hint" | The value of the hint variable |
:title="'hint'" | The string hint (a string literal) |
:disabled="total === 0" | true or false |
If a boolean attribute like disabled evaluates to false, Vue removes the attribute entirely.
Printing HTML
Interpolation always prints text: the string '<b>important</b>' appears on the page with its angle brackets. This protects against injected code. To insert ready-made HTML there is the v-html directive, but use it only for markup you trust — never for text typed by a user.
Common mistake
Double curly braces inside an attribute do not work:
<!-- Wrong: the attribute gets the text with curly braces -->
<img src="{{ logo }}">
<!-- Right -->
<img :src="logo">Always use the colon for attributes.