Template syntax and v-bind

Vue · Essentials · 10 min

Templates are where most Vue code lives; reading and writing bindings fluently is the first real Vue skill.

A Vue template is valid HTML extended with bindings. Text interpolation uses double curly braces: {{ user.name }} renders the value as text (HTML is escaped, so it is safe against injection).

Inside {{ }} and directive values you write JavaScript expressions, not statements: {{ price * qty }}, {{ ok ? 'Yes' : 'No' }} and {{ formatDate(d) }} work; if blocks and variable declarations do not.

Attributes are not interpolated. To bind one to data, use the `v-bind` directive, almost always with its : shorthand:

  • :src="avatarUrl", :disabled="isSaving" — a false, null or undefined boolean value removes the attribute.
  • :id alone (same-name shorthand, Vue 3.4+) means :id="id".
  • v-bind="attrsObject" spreads an object of attributes.
  • :[attrName]="value" binds a dynamic attribute name.

:class and :style are special: they accept objects and arrays, so :class="{ active: isActive, 'text-danger': hasError }" toggles classes and merges with a static class attribute.

A directive is an attribute starting with v- whose value is an expression that Vue re-evaluates whenever its reactive dependencies change. You will meet v-if, v-for, v-on and v-model next. v-html renders raw HTML: use it only with content you trust.

Example

<script setup>
import { ref } from 'vue'

const user = ref({ name: 'Ada', avatar: '/ada.png' })
const isSaving = ref(false)
const hasError = ref(true)
const id = 'profile'
</script>

<template>
  <section :id>                                <!-- same as :id="id" -->
    <img :src="user.avatar" :alt="`Avatar of ${user.name}`">
    <p>{{ user.name.toUpperCase() }}</p>       <!-- ADA -->
    <p :class="{ error: hasError, saving: isSaving }">Status</p>
    <!-- renders class="error" -->
    <button :disabled="isSaving">Save</button>  <!-- no disabled attr -->
  </section>
</template>

Remember

  • {{ expr }} renders escaped text; directives take JavaScript expressions
  • :attr="expr" is shorthand for v-bind:attr; falsy booleans remove the attribute
  • :class and :style accept objects and arrays

Watch out for

  • Writing src="{{ url }}"; attributes need :src="url", mustaches only work in text.

Check yourself

  1. Which binding correctly sets an image's src from the `url` variable?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: vuejs.org/guide/essentials/template-syntax.html