Rendering

Simple data

Given appName is a piece of data supplied by the app:

<h1>{{ appName }}</h1>

Lists

For simple arrays, such a list of colours: colors: ['red', 'green', 'blue', 'yellow', 'orange', 'purple', 'magenta', 'black', 'white']:

<ul>
	<li v-for="(color, index) in colors">{{ index }}: {{ color }}</li>
</ul>

For arrays of objects, we can use the dot notation. Given:

const app = Vue.createApp({
  data() {
    return {
      ...,
      capitals: [
        { name: 'London', country: 'UK' },
        { name: 'Paris', country: 'France' },
        { name: 'Berlin', country: 'Germany' },
        { name: 'Rome', country: 'Italy' },
        { name: 'Madrid', country: 'Spain' },
        { name: 'Buenos Aires', country: 'Argentina' }
      ]
    }
  }
});

We can display them:

<div v-for="capital in capitals" :key="capital.name">
	{{ capital.name }}, {{ capital.country }}
</div>

The binded key helps Vue identifying them - keys should be string or numeric values.

Binding

Dynamically bind an attribute to an expression

Given image is a piece of data supplied by the app:

<img v-bind:src="image">
<img :src="image"> // Shorthand

Style binding

Sometimes the value is part of an object that need binding:

<div :style="{ backgroundColor: someColor }"></div>

`backgroundColor` (camelCase version of the property required in JS) is "converted" to the css property `background-color`. Alternatively, we can use the css property name in quotes:

<div :style="{ 'background-color': someColor }"></div>

For multiple properties:

<div :style="{ backgroundColor: someColor, color: someOtherColor }"></div>

... it is easier to bind to an object property:

<div :style="styleObject"></div>

'styleObject' will be defined inside our app:

const app = Vue.createApp({
  data() {
    return {
      ...,
      styleObject: {
        backgroundColor: 'red',
        color: 'white'
      }
    }
  }
});

Class binding

<button :class="{ disabled: !isActive }">Add</button>

Class names are the keys and they are added based on the truthiness of the corresponding value. In our example class "disabled" is added if "isActive" is false.

If the element already has an assigned class:

<button class="someStyle" :class="{ disabled: !isActive, active: isActive }">Add</button>

... if the condition is true, the class is simply added to the element and behave in the "traditional" way:

<button class="someStyle disabled">Add</button>

2-way binding

When properties need to be updated as well as read:
<div id="app">
  <h1>{{ appName }}</h1>
  <input v-model="appName">
</div>

Conditional Rendering

"if/else"

Displays one or the other tags based on the condition:
<p v-if="wasCompleted">Completed</p>
<p v-else>Active</p>

NB: the `v-else` is optional but, if present, must be on the same level as the `v-if`.

Conditional expressions can also be used:

<p v-if="score > 50">Completed</p>
<p v-else>Active</p>

"if/else-if/else"

<p v-if="score > 50">Completed</p>
<p v-else-if="score > 40">Almost there</p>
<p v-else>In progress</p>

"show"

Toggles an element's visibility:
<p> v-show="wasCompleted">Completed</p>
End result if condition is not met:
<p> style="display: none;">Completed</p>

Forms

Prevent default submit and use a local method to process the form:

<form @submit.prevent="onSubmitForm"> 50">
...
</form>

The onSubmitForm method will be added to the app or component methods list.

...
data() {
  ...
},
methods: {
  onSubmitForm() {
    ...
  }
}
...