Vue.js Templating

Templating allows to bind values from the model into the view. In Vue, this can be achieved using simple HTML bindings.

From version 2 onwards, Vue.js allows for raw JavaScript templating (React-style) in addition to HTML templating. This post will cover HTML templating.

Starting off from this Vue.js Hello World example, let’s use the following data model:

data() {
  return {
    text: 'Hello world',
    htmlContent: 'Hello bold new world!',
    isDisabledAttr: true


Interpolation refers to the act of taking one or more variables, evaluating their values, and displaying the result in the template. It can be as simple as a ‘Hello World’ string, but it can also be the result of a more complex expression.


The most basic version is using double curly braces, commonly known as the mustache syntax. This would create a one-way data binding from the model to the template. Displaying the raw value in the template.

One way binding refers to the binding method where data is sent from the model to the view, but not the other way around.

<span>Text binding: {{ text }}</span><br>

The above example would simply take the appropriate text value from the data model and display it’s value instead of the {{ text }} tag.

One time binding

We can use the v-once directive to bind once and stop tracking the item.

Using v-once means that a later change to the value in the model does not affect the displayed value in the template.

<span v-once>Text binding: {{ text }}</span><br>

The usage of v-once in this binding means that if the text value is later changed, the value inside the span tag still displays the initial value.


Binding a string containing HTML tags using the previously discussed methods will print out the expression as a plain string.

If we need to evaluate the tags in the HTML, and we trust the source of the HTML, we can use the v-html to ask Vue to evaluate the string as HTML.

<span v-html="htmlContent"></span>

The content in the htmlContent would be evaluated as html and inserted in to the span when using the v-html directive.


In addition to values, we can add attributes to elements using Vue templating. Instead of the mustache syntax, we can use the v-bind directive to bind values from the model into attributes.

<button v-bind:disabled="isDisabledAttr">

<button :disabled="isDisabledAttr">

The above example takes the isDisabledAttr from the model and set it to the disabled attribute on the button tag.

Instead of using the v-bind:attr=modelValue syntax, we can simply use the shorter :attr=modelValue syntax to the same effect.

JS Expressions

Vue supports evaluating simple expressions inside data bindings.

<span>{{ text + ' ' + isDisabledAttr }}</span>

The example prints the concatenated string: ‘Hello world true’.

The Vue syntax allows us to have one expression inside the double curly braces. This can’t include control flows or multiple expressions.


Vue provides a set of built-in directives prefixed with v- that allow DOM manipulation inside the template in response to model changes.

For example, the v-if directive would show/hide an element based on the model value.

We can create custom directives as well to do custom DOM manipulations depending on the input.


Filters can be used with model values to modify the given value for displaying in the view.

For example, you may want to display some text in all caps. Here, rather than modifying or duplicating the initial model value, we can apply a filter that will dynamically transform the value for the display.

In order to achieve this, we need to create a filter:

filters: {
  allCaps: function (value) {
    if (!value) return '';
    value = value.toString();
    return value.toUpperCase();

The allCaps function simply takes a string and returns a string in all caps.

In the view, we can use the filter to transform the display value to uppercase without changing the initial model value.

<span>{{ text | allCaps }}</span>

Here, instead of the ‘Hello World’ value that’s stored in the model, Vue will display ‘HELLO WORLD’ in all caps since the filter is applied before the value is sent to the view.

See on JSFiddle


🔎 Searching...