VueJs Directives: List Rendering
Created on April 3, 2022.
Resuming from where we ended on the previous post, we covered conditional rendering inside Vue, with the help of the v-if, v-else-if, and v-else directives.
In this post, we are going to cover list rendering in Vue, simply put, we are going to learn how to list data with the same schema in list-like presentation, within the Vue templates.
The v-for Directive
To render lists in Vue, you need to use the v-for directive. In the same vein of application, the v-for directive resembles JavaScript’s forEach, which lets you iterate through Arrays, Object properties, and ranges.
Array rendering
Let’s look at the following example.
<html>
<div id="app">
<h2>Array</h2>
<ul>
<li v-for="fruit in fruits">{{ fruit }}</li>
</ul>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
let app = Vue.createApp({
data() {
return {
fruits: ['Oranges', 'Apples', 'Watermelons', 'Pears'],
color: "Red"
}
}
}).mount("#app");
</script>
</html>
The above example renders the fruits in an unordered list.
The v-for directive requires a special syntax in the form item in items
, where items is the source of data being iterated upon and item, being the active scope of the element being iterated. of
can also be used in place of the in
delimiter, resulting to item of items
to get the v-for special syntax close to that of JavaScript’s iterations.
Thus, we can run the above iteration as follows:
<ul>
<li v-for="fruit of fruits">{{ fruit }}</li>
</ul>
We can also get the location of the item being iterated on inside its source Array by getting an optional second alias of the current item.
<ul>
<li v-for="(fruit, index) of fruits">
{{ index }} -> {{ fruit }}
</li>
</ul>
The scope of a v-for directive element has access to the current item being iterated on and all parent scope. Though, it does not have access to other elements’ scopes. In our example above, the color variable can be accessed inside the v-for scopes as follows.
<ul>
<li v-for="(fruit, index) of fruits">
{{ color }} {{ fruit }}
</li>
</ul>
Hence, the above code would give us “Red Oranges”, “Red Pears” and so on.
Rendering in Ranges
We can iterate through ranges with the v-for directive by providing an Integer that acts as the nth value in a range of 1…n-1,n, hence, iteration will start from 1 to n.
The following code exemplifies this:
<ul>
<li v-for="num in 10">
{{ num }}
</li>
</ul>
Object Rendering
v-for can also be used to iterate through Object properties, i.e Object keys, values or both.
Like with arrays, we can also derive the index of the property position in the Object in a third alias.
<html>
<div id="app">
<h2>Object - Index, Keys and Values</h2>
<ul>
<li v-for="(value, key, index) in categories">[{{ index }}] {{ key }}: {{ value }}</li>
</ul>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
let app = Vue.createApp({
data() {
return {
categories: {fruit: 'Orange', animal: 'Lion', vehicle: 'Mini-van', sport: 'Football'}
}
}
}).mount("#app");
</script>
</html>
In Object iteration the order is based on the result returned from JavaScript’s Object.keys()
.
v-for’s Key Attribute
When a list is updated, Vue patches each element in-place, making sure it reflects what is to be rendered in a particular index instead of reshuffling around all DOM elements to the new state.
To avoid unexpected results, Vue should neither rely on child components’ nor temporary DOM states.
Vue needs a hint that it can use to track each node’s identity to reuse and reorder existing elements efficiently. Thus, we should provide a key
attribute with v-for whenever possible, unless the iterated DOM contains no components or stateful DOM elements.
The key
attribute expects Strings, Numbers and Symbols (Primitive values), we should never provide Objects as v-for keys.
The following example shows us how to implement the key attribute in v-for iteration.
<html>
<div id="app">
<h2>v-for with key attribute</h2>
<ul>
<li v-for="(employee, key) of employees" :key="key">
Name: {{ employee.name }} <br>
Role: {{ employee.role }} <br>
Experience: {{ employee.experience }} years
<br>
<br>
</li>
</ul>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
let app = Vue.createApp({
data() {
return {
employees: [
{
name: "John Wick",
role: "Front-End Developer",
experience: 4
},
{
name: "Sylvester Stallone",
role: "Senior Developer",
experience: 8
},
{
name: "Mary Jane",
role: "Developer Relations",
experience: 2
}
]
}
}
}).mount("#app");
</script>
</html>
No visible change is to be expected from this implementation other than culling the chances of unexpected results, consider this a v-for best practice if you currently find it tough to grasp. More on list rendering will be covered in a later post.
Next
VueJs Directives: Class and Style Binding
Previous