Templates and Directives

By Syncfusion®, Inc. · Last updated

Declarative rendering, text interpolation with {{ }}, JavaScript expressions in templates and their limits, the parts of a directive, v-bind and its : shorthand, boolean and multiple attributes, v-html and XSS, v-text, v-once, v-memo, v-pre, v-cloak and template scope.

Templates

  • A template is the HTML part of a Vue component. It sits inside <template>.
  • It looks like normal HTML, with a few extra Vue rules.
  • Vue reads the template and builds the page from it.
  • When your data changes, Vue updates the page to match the template again.

Simple lesson: the template is a picture of the page. Vue keeps the real page looking like that picture.

A Real-World Example

  • Meera's menu card shows a dish name, a price and a "Veg" label.
  • The name and price come from her code, not from typed HTML.
  • If she changes the price in her code, the card must change too.
  • A Vue template does this with {{ }} and : bindings.
  • What happened: {{ dish }} showed the dish name.
  • {{ isVeg ? "Veg" : "Non-veg" }} picked the right label.
  • :alt="dish" put the dish name inside the image's alt attribute.

What You Will Learn

  1. What declarative rendering means.
  2. How to show values with {{ }}.
  3. Which JavaScript you can write inside a template.
  4. The parts of a directive.
  5. How to bind attributes with v-bind and :.
  6. How to bind boolean attributes and many attributes at once.
  7. Why v-html can be dangerous.
  8. What v-text, v-once, v-memo, v-pre and v-cloak do.
  9. Which names a template can use.

Declarative Rendering

  • Declarative = you say what the page should show, not how to change it.
  • Imperative = you write every step yourself: find the element, then change its text.
  • Vue templates are declarative.
  • You never call document.querySelector to update text.
Imperative (plain JavaScript)Declarative (Vue template)
el.textContent = "₹" + price<p>₹{{ price }}</p>
You must run it after every changeVue runs it for you
Easy to forget one placeThe template is the one place

Simple lesson: describe the page once. Vue keeps it right.

Text Interpolation

  • Interpolation = putting a value inside text.
  • Vue uses double curly braces: {{ value }}. People call them "mustaches".
  • The value is turned into text.
  • null and undefined show nothing. An object or array is shown as JSON text.
  • Vue updates the text when the value changes.

Animation: the value of price flows from the script into the mustache in the template and appears as text on the screen

script price = 90

template

screen ₹90

The mustache is a hole in the text. Vue fills it with the value.

Vue copies the value into the mustache and shows it as text.

JavaScript Expressions

  • An expression = a piece of code that gives back a value.
  • You can write one expression inside {{ }}.
  • Maths: {{ price * 2 }}.
  • Text: {{ dish.toUpperCase() }}.
  • A choice: {{ isVeg ? "Veg" : "Non-veg" }}.
  • A function call: {{ formatPrice(price) }}.
  • What happened: each {{ }} ran one expression and showed its result.

What You Cannot Write

  • Only one expression is allowed. Statements are not.
  • {{ let total = 5 }} fails. That is a statement.
  • {{ if (isVeg) { ... } }} fails. Use the ? : choice instead.
  • Keep templates simple. Move long logic into a function in the script.
  • A function called in the template runs again on every update. For values worked out from state, computed is better (next lesson but one).

A template error stops the whole component from compiling. The Console names the file and the line, so read it first when the preview stays empty.

Simple lesson: {{ }} shows one expression as text. No statements inside.

The Parts of a Directive

  • A directive = a special attribute that starts with v-.
  • It tells Vue to do something to that element.
  • A directive can have four parts.

Animation: the four parts of v-on:submit.prevent="save" light up one by one. Name, argument, modifier, value

v-on : submit .prevent = "save"

Name: which directive (v-on listens for events) Argument: after the colon (which event: submit) Modifier: after a dot (an extra rule: prevent the page reload) Value: inside the quotes (a JavaScript expression: save)

Name, argument, modifier, value. Not every directive uses all four.

  • Name = which directive, such as v-bind or v-on.
  • Argument = what it works on, after a colon: v-bind:href.
  • Dynamic argument = an argument in square brackets, taken from a variable: v-bind:[attrName].
  • Modifier = an extra rule after a dot: .prevent.
  • Value = a JavaScript expression inside the quotes.

Shorthands

  • v-bind:href is written :href most of the time.
  • v-on:click is written @click. You will learn it in Events and Forms.
  • v-slot:header is written #header. You will learn it in Slots, Attributes and Provide/Inject.

Simple lesson: a directive is v-name:argument.modifier="value".

Binding Attributes with v-bind

  • {{ }} only works inside text. It does not work inside an attribute.
  • To put a value into an attribute, use v-bind, or : for short.
  • :href="link" means "set href to the value of link".
  • Without the colon, href="link" is just the plain text "link".
  • Same-name shorthand (Vue 3.4): when the variable has the same name as the attribute, :id="id" can be written :id.
  • What happened: the first two links point to the real address.
  • The third link points to the text "menuLink", because it has no colon.
  • :[field] used the variable field, so it set the title attribute.

If an attribute shows your variable's name instead of its value, you forgot the colon.

Boolean Attributes

  • A boolean attribute is on or off, such as disabled or checked.
  • :disabled="true" adds the attribute.
  • :disabled="false" removes it. So do null and undefined.
  • An empty string "" keeps the attribute, because disabled="" means "on" in HTML.
  • Here the button turns off when the dish is sold out.

Binding Many Attributes at Once

  • You can bind a whole object with v-bind="object" (no argument).
  • Each key becomes an attribute.
  • This is useful when many attributes belong together.

Simple lesson: use : to put a value into an attribute. Use v-bind="object" for many at once.

v-html and Safety

  • {{ }} always shows text. HTML tags inside the value appear as plain text.
  • v-html puts the value in as real HTML.
  • That is risky. If the HTML comes from a user, it can run their code.
  • This attack is called XSS (cross-site scripting).
  • Also, <style scoped> rules do not reach HTML added by v-html. Style it with a global or :deep() rule.
  • What happened: the mustache showed the <b> tag as text.
  • v-html made the text bold.
  • The visitor's "review" ran code. The Console below the preview shows it.

Only use v-html for HTML that you wrote or fully trust. Never use it for text typed by users, comments or reviews. Show those with {{ }}.

Simple lesson: {{ }} is safe text. v-html is real HTML, so trust it first.

More Built-In Directives

  • v-text = sets the whole text of an element. Same as {{ }} for the full content.
  • v-once = shows the value once. Later changes are ignored.
  • v-memo = skips an update unless listed values change. It is for speed in big lists. See Performance.
  • v-pre = shows the template code as it is. Vue skips this part.
  • v-cloak = hides the raw {{ }} until Vue is ready. Only useful with the CDN build.
  • What happened: after 1.5 seconds, the first line changed to Pongal.
  • The v-once line still says Idli.
  • The v-pre line shows the mustache itself.

v-cloak with the CDN

  • With the CDN, the browser shows your HTML before Vue starts.
  • For a moment, people can see {{ special }} on the page.
  • v-cloak plus one CSS rule hides it until Vue is ready.
  • Build-tool projects compile templates first, so they do not need it.
<style>
  [v-cloak] { display: none; }
</style>

<div id="app" v-cloak>{{ special }}</div>

Simple lesson: v-once freezes, v-pre skips, v-cloak hides until ready.

Template Scope

  • A template can use everything at the top of <script setup>: variables, functions and imports.
  • It can also use a short list of safe globals, such as Math, Date, JSON and Number.
  • It cannot use other globals like window or document.
  • If you need one, wrap it in a function in the script.

Writing window.innerWidth straight in a template gives a warning that window is not defined, in a real project and in this lab. Calling a script function, as above, works.

Simple lesson: templates see your script's names and a few safe globals.

TL;DR

  • Template = the HTML part of a component, inside <template>.
  • Declarative = you describe the page, Vue does the updates.
  • {{ }} = shows one JavaScript expression as text.
  • Directive = a v- attribute: name, argument, modifier, value.
  • :attr = short for v-bind:attr. Puts a value into an attribute.
  • Boolean binding = :disabled="false" removes the attribute.
  • v-bind="obj" = binds every key of an object as an attribute.
  • v-html = real HTML. Only for HTML you trust.
  • v-once / v-pre / v-cloak = freeze / skip / hide until ready.

Common mistakes

MistakeWrong ideaCorrect ideaWhat goes wrong
{{ }} inside an attributehref="{{ link }}" worksWrite :href="link"Vue gives a compile error
Forgetting the colonsrc="photo" uses the variableWrite :src="photo"The attribute holds the word photo
Statements in {{ }}{{ if (x) ... }} is fineUse x ? a : b or a functionThe template does not compile
v-html with user textIt is just formattingShow user text with {{ }}Strangers can run code on your page (XSS)
Long logic in the templateTemplates can hold anythingMove it to a functionHard to read and test
Using window in a templateAll globals workWrap it in a script functionA warning, and the value is missing
v-cloak in a Vite projectEvery app needs itOnly CDN pages need itExtra code that does nothing

Check Yourself

Exercises

What to Remember

  • Templates are declarative: describe the page, Vue updates it.
  • {{ }} shows one expression as text. It never goes inside an attribute.
  • Use :attr="value" to bind attributes. A missing colon means plain text.
  • v-html inserts real HTML. Never use it for user text.
  • A template can use script names and a few safe globals like Math.

Next: Reactive State