beginner Step 2 of 15

Template Syntax

Vue.js Development

Template Syntax

Vue uses an HTML-based template syntax that allows you to declaratively bind the rendered DOM to the underlying component instance's data. Templates are compiled into virtual DOM render functions, which Vue uses to efficiently update the real DOM when data changes. The template syntax includes text interpolation with double curly braces, directives prefixed with v- for reactive behavior, and shorthand notations that keep templates concise and readable. Understanding template syntax is fundamental to everything you build in Vue.

Text Interpolation

The most basic form of data binding is text interpolation using the mustache syntax (double curly braces). The content is replaced with the value of the corresponding property from the component instance and updates reactively.

<template>
  <div>
    <!-- Basic interpolation -->
    <h1>{{ title }}</h1>
    <p>Welcome, {{ userName }}!</p>

    <!-- Expressions are supported -->
    <p>Total: ${{ (price * quantity).toFixed(2) }}</p>
    <p>Status: {{ isActive ? "Active" : "Inactive" }}</p>
    <p>{{ message.split("").reverse().join("") }}</p>

    <!-- Raw HTML with v-html (use carefully — XSS risk) -->
    <div v-html="htmlContent"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: "My Vue App",
      userName: "Alice",
      price: 29.99,
      quantity: 3,
      isActive: true,
      message: "Hello Vue",
      htmlContent: "<strong>Bold text</strong>",
    };
  },
};
</script>

Attribute Binding with v-bind

Mustaches cannot be used inside HTML attributes. Instead, use the v-bind directive to dynamically bind attribute values. The shorthand is a colon (:).

<template>
  <div>
    <!-- Full syntax -->
    <img v-bind:src="imageUrl" v-bind:alt="imageAlt" />

    <!-- Shorthand (preferred) -->
    <img :src="imageUrl" :alt="imageAlt" />

    <!-- Dynamic class binding -->
    <div :class="{ active: isActive, 'text-danger': hasError }">
      Dynamic classes
    </div>

    <!-- Array class binding -->
    <div :class="[baseClass, isActive ? 'active' : '']">
      Array classes
    </div>

    <!-- Dynamic style binding -->
    <div :style="{ color: textColor, fontSize: fontSize + 'px' }">
      Styled text
    </div>

    <!-- Boolean attributes -->
    <button :disabled="isSubmitting">Submit</button>

    <!-- Dynamic attribute name -->
    <a :[attributeName]="url">Link</a>
  </div>
</template>

<script>
export default {
  data() {
    return {
      imageUrl: "/photo.jpg",
      imageAlt: "A photo",
      isActive: true,
      hasError: false,
      baseClass: "container",
      textColor: "blue",
      fontSize: 16,
      isSubmitting: false,
      attributeName: "href",
      url: "https://vuejs.org",
    };
  },
};
</script>

Event Handling with v-on

The v-on directive listens for DOM events and executes JavaScript when they are triggered. The shorthand is @.

<template>
  <div>
    <!-- Full syntax -->
    <button v-on:click="handleClick">Click me</button>

    <!-- Shorthand (preferred) -->
    <button @click="count++">Count: {{ count }}</button>

    <!-- Method handler -->
    <button @click="greet('Hello')">Greet</button>

    <!-- Access the event object -->
    <button @click="logEvent($event)">Log Event</button>

    <!-- Event modifiers -->
    <form @submit.prevent="onSubmit">
      <input @keyup.enter="search" />
      <button type="submit">Submit</button>
    </form>

    <!-- Key modifiers -->
    <input @keyup.escape="clearInput" />
  </div>
</template>

<script>
export default {
  data() {
    return { count: 0 };
  },
  methods: {
    handleClick() {
      console.log("Button clicked!");
    },
    greet(message) {
      alert(message);
    },
    logEvent(event) {
      console.log("Event type:", event.type);
    },
    onSubmit() {
      console.log("Form submitted");
    },
    search() {
      console.log("Searching...");
    },
    clearInput() {
      console.log("Input cleared");
    },
  },
};
</script>
Tip: Always use the shorthand syntax (: for v-bind and @ for v-on) in your templates. It is more concise, widely adopted by the community, and used in all official Vue documentation examples.

Key Takeaways

  • Text interpolation uses {{ }} mustache syntax and supports JavaScript expressions.
  • v-bind (shorthand :) dynamically binds HTML attributes, classes, and styles.
  • v-on (shorthand @) listens for DOM events and calls methods or inline expressions.
  • Event modifiers like .prevent, .stop, and .enter simplify common event handling patterns.
  • Use v-html sparingly for raw HTML — it bypasses Vue's template compilation and poses XSS risks.