Learn Vue: List and Conditional Rendering.
Tags: javascript, webdev, programming, vue
Published: 2023-08-13 22:34:35

Imaging you are developing an application, and you want to render some data in the browser based on certain conditions or you have an array of data that you want to loop through and display to in the browser, how can we achieve this Vue? In this guide, we we'll learn `List rendering` and `conditional rendering` in Vue and how we can tap into the powers of the `v-if` and the `v-for` directives.

## List Rendering
The `v-for` directive is used to render an array of items or an object. The syntax is very simple and easy; `item in items` where item is the individual `item` that would be rendered and `items` is the list we are looping through.

### Rendering array with v-for
```js
//template
<div v-for="name in names">{{ name }}</div>

//script

const names = ref(["Vue", "Nuxt", "Vite", "Vitepress"]
```
`v-for` will loop through the `names` array and display each of name in the browser.

### Rendering object with v-for
The `v-for` can also be used to iterate through an object, the sequence of the iterations will rely on the outcome of invoking `Object.keys()` on the object:

```js
//template
<ul>
  <li v-for="value in myObject">
    {{ value }}
  </li>
</ul>

//script
const myObject = reactive({
  title: 'How to render lists in Vue',
  author: 'KingstonCodes',
  publishedAt: '2023-08-10'
})
```
Optionally, we can also include the key of each property in the object `<li v-for="(value, key) in myObject"> {{ value }} </li>`

### v-for and key
In order to maintain the state of the items when rendering them to the browser, we can introduce a unique `key` attribute to reference to each item in the list:

```js
<div v-for="item in items" :key="item.id">
 {{ item }}
</div>
```
The `v-for` directive is extremely important as it helps us render lists to the browser effortlessly.

## Conditional Rendering

We can render anything to the browser conditionally using either the `v-show` directive or the `v-if` directive. Both  `v-show` and `v-if` can be used to achieve the same result, the difference is that the `v-show` directive only toggles the CSS `display` property of the element, hence an element with the v-show directive will always be present in the browser.

### v-show

Let's see an example of conditional rendering with the `v-show` directive.

```js
<div v-show="isTrue">
//content here
</div>

//script
const isTrue = ref(true)
```
The `div` will always be rendered in the browser as long as `isTrue` remains `true`, likewise, when `isTrue` is `false` the `div` disappears from the browser.

### v-if
Like the `v-show` directive, the `v-if` directive is also used to conditional render elements to the browser, the element is only rendered when the directive's expression returns a truthy value.

```js
<div v-if="isTrue">
//content here
</div>

//script
const isTrue = ref(true)
```
Another difference between the `v-if` directive and the `v-show` directive is that, we can use `v-else` and `v-else-if` directives to match cases where the directives expression isn't true.

### v-if with v-else and v-else-if
```js
<div v-if="isTrue < 0">
//display content here
</div>

<div v-else-if="isTrue > 0">
//display content here
</div>

<div v-else>
//display content here
</div>

//script
const isTrue = ref(0)
```
Like the traditional `if`, `else if`, and `else` in JavaScript, the `v-if`, `v-else` and `v-else-if` can be used to achieve similar result.

In the above example, the `v-else` block will run because `isTrue` is neither less than or greater than zero. Similarly, the `v-if` block or `v-else-if` block will run depending on whether `isTrue` is greater than or less than `0`

## v-for with v-if
Sometimes, we might want to render a list to the browser when certain conditions are met, to achieve this, we need to first loop through the list with `v-for` then check whether the condition is met with `v-if` before displaying it.

The problem is, it is not a good practice to use the `v-for` and `v-if` directives on the same element, because when they exist on the same element, `v-if` will have higher level of priority over `v-for`, meaning that `v-if` will not be able to access the variable from the `v-for` block.

```js
<!--
This will not work
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo.name }}
</li>
```
To fix this, let's move the `v-for` directive to a wrapper tag.

 

```js
<template v-for="todo in todos"> 
<li v-if="!todo.isComplete">
  {{ todo.name }}
</li>
</template>
```
And that's it, the `v-for` block will always execute before the `v-if` block, thereby allowing the `v-if` directive access to the `v-for` variable and carry out the action.