Book Image

Frontend Development Projects with Vue.js 3 - Second Edition

By : Maya Shavin, Raymond Camden, Clifford Gurney, Hugo Di Francesco
5 (2)
Book Image

Frontend Development Projects with Vue.js 3 - Second Edition

5 (2)
By: Maya Shavin, Raymond Camden, Clifford Gurney, Hugo Di Francesco

Overview of this book

Are you looking to use Vue.js 3 for building web apps but don't know where to begin? Frontend Development Projects with Vue.js 3 will help you get to grips with the core concepts of this JavaScript framework using practical examples that simulate real-world web projects. With this updated edition, you’ll experience all aspects of the new and improved Vue.js 3 as you work on mini projects such as a chat interface, a shopping cart, a price calculator, a to-do app, and a profile card generator for storing contact details. These realistic projects are presented as bite-size exercises that you can enjoy even as you challenge yourself. Throughout the book, you'll discover how to manage data in Vue components, define communication interfaces between components, and handle static and dynamic routing to control application flow. You'll also work with Vite and Vue DevTools and learn how to handle transition and animation effects for an engaging user experience. Finally, you’ll see how to test your app and deploy it to the web. By the end of this Vue.js book, you'll have the skills that enable you to work like an experienced Vue developer to build professional apps that can be used by others and have the confidence to tackle real-world frontend web development problems.
Table of Contents (20 chapters)
1
Part 1: Introduction and Crash Course
5
Part 2: Building Your First Vue App
11
Part 3: Global State Management
14
Part 4: Testing and Application Deployment

Understanding data iteration with v-for

To loop over HTML elements in Vue, you use the v-for loop directive directly on the target elements. When Vue renders the component, it will iterate the target to use and render the data being parsed into the directive, with the same concept as a normal JavaScript for loop.

Basic iteration using v-for

The basic syntax of v-for is as follows:

v-for="(item, index) in items" :key="index"

The preceding syntax example indicates that we are iterating through a list of items. We have access to a single item and its appearance index in the list in each iteration. :key is a required attribute, acting as the unique identifier of each iterating element rendered for the Vue engine to keep track.

When the key or item content changes, either programmatically or due to user interactions, the Vue engine triggers an update of the changed item on the UI. If you have multiple loops in one component, you should randomize the key attribute with extra characters or context-related strings to avoid key duplication conflicts.

There are various use cases for this direction. One straightforward use case is to perform anonymous loops, in which you can define a number, X, as a symbolic list, and the loop will iterate that X times. This can be handy in situations in which you strictly control the number of iterations you want or render some placeholder content.

In the following example, we see an anonymous loop in which the total iterations are 2 and we define key with a loop-1 prefix:

<template>
<div v-for="n in 2" :key="'loop-1-' + n">
    {{ n }}
</div>
<template>

You can also use template literals (with `` backticks) to compute strings without +:

<template>
<div v-for="n in 5" :key="`loop-2-${n}`">
    {{ n }}
</div>
<template>

The output of the preceding code in both approaches should look as follows

Figure 1.18 – Output of anonymous loops example

Figure 1.18 – Output of anonymous loops example

Now that we have covered how to handle basic loops by using v-for, we will utilize this function in the next exercise.

Exercise 1.05 – using v-for to iterate through an array of strings

In this exercise, we are going to create an anonymous loop using Vue’s v-for directive. This will be familiar to those who have used for or forEach loops in JavaScript before.

To access the code file for this exercise, refer to https://github.com/PacktPublishing/Frontend-Development-Projects-with-Vue.js-3/tree/v2-edition/Chapter01/Exercise1.05.

Perform the following steps to complete the exercise:

  1. Use the application generated with npm init vue@3 as a starting point, or within the root folder of the code repository, navigate into the Chapter01/Exercise1.05 folder by using the following commands in order:
    > cd Chapter01/Exercise1.05/
    > yarn
  2. Run the application using the following command:
    yarn dev
  3. Open the exercise project in VS Code (by using code . command within the project directory) or your preferred IDE.
  4. Create a new Vue component file named Exercise1-05.vue in the src/components directory.
  5. Inside Exercise1-05.vue, we compose a new component with an <h1> element to render the static title of Looping through arrays, and an <ul> element containing an empty <li> tag:
    <template>
    <h1>Looping through arrays</h1>
    <ul>
      <li></li>
    </ul>
    </template>
  6. In the script section, let’s add a setup attribute to the script tag. Then, let’s declare an array of interests containing some strings as follows:
    <script setup>
    const interests = ['TV', 'Games', 'Sports']
    </script>
  7. Now, let’s go back to the template section and add the v-for directive on the <li> tag to iterate through interests. For each iteration, we get a combination of (item, index) from the interests, in which item outputs the string of the array, and index is the loop index. We map the key attribute to index, and display the value of item as shown in the following code block:
    <template>
    <h1>Looping through arrays</h1>
    <ul>
      <li v-for="(item, index) in interests"
         :key="index">{{ item }}</li>
    </ul>
    </template>
  8. Go to https://localhost:3000. The following output is as follows:
Figure 1.19 – Output of iterating through an array of strings

Figure 1.19 – Output of iterating through an array of strings

In this exercise, we learned how to iterate through a specific array of strings, outputting the string value or index of an array. We also learned that the key attribute needs to be unique to avoid DOM conflicts and forces the DOM to re-render the component properly.

Next, let’s experiment with iterating a collection of objects.

Iterating through an array of objects

In most practical scenarios, we work with data as objects, especially when iterating through an array of objects. Vue makes it easy to control various data states through its directive syntax. Like iterating through an array of strings, the directive syntax remains the same:

v-for="(item, index) in items" :key="index"

The item you receive is now an Object, with various properties. You can bind each property using what you have learned so far to display its value. For example, assume in item, we will have id, title, description, and another array, characteristics, containing some strings. We can display the title and description information for each item like so:

<template>
  <ul>
    <li v-for="(item, index) in items" :key="item.id">
      <h2>{{ item.title }}</h2>
      <span>{{ item.description }}</span>
    </li>
  </ul>
</template>

Note here we don’t use an index as the key; instead, we use id as the unique identifier for key. It is considered a more secure approach to use id or any other unique identifier and we also don’t need to include index in the syntax in this case since we don’t use it.

Since characteristics is an array, we display its values by using a v-for directive again for characteristics. You don’t have to use the same name, item, that the syntax example shows. Instead, you can give it a different name depending on how you want your variable to be.

In the following example, we use str for each element in the item.characteristics array:

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <h2>{{ item.title }}</h2>
      <span>{{ item.description }}</span>
      <ul>
          <li v-for="(str, index) in item.characteristics"
           :key="index">
             <span>{{ str }}</span>
          </li>
      </ul>
    </li>
  </ul>
</template>

And in the script section, we define items as follows:

<script setup>
const items = [{
  id: 1,
  title: "Item 1",
  description: "About item 1",
  characteristics: ["Summer", "Winter", "Spring", "Autumn"]
}, {
  id: 2,
  title: 'Item 2",
  description: 'About item 2",
  characteristics: ["North", "West", "East", "South"]
}]
</script>

The preceding code will output as shown in Figure 1.20:

Figure 1.20 – Output of iterating through an array of object items

Figure 1.20 – Output of iterating through an array of object items

Understanding how to loop through collections of objects with v-for is essential and useful for handling data, especially with external data. In the next exercise, you will combine v-for and v-if to display a list of objects conditionally.

Exercise 1.06 – using v-for to iterate through an array of objects and using their properties in v-if conditions

In this exercise, we will be controlling a Vue data array and iterating through the objects inside of it.

To access the code file for this exercise, refer to https://github.com/PacktPublishing/Frontend-Development-Projects-with-Vue.js-3/tree/v2-edition/Chapter01/Exercise1.06.

Let’s start the exercise by performing the following steps:

  1. Use the application generated with npm init vue@3 as a starting point, or within the root folder of the code repository, navigate into the Chapter01/Exercise1.06 folder by using the following commands in order:
    > cd Chapter01/Exercise1.06/
    > yarn
  2. Run the application using the following command:
    yarn dev
  3. Open the exercise project in VS Code (by using the code . command within the project directory) or your preferred IDE.
  4. Create a new Vue component file named Exercise1-06.vue in the src/components directory.
  5. Inside Exercise1-06.vue, create an array of data objects, interests, as local data. Each interest contains a title string and a favorites array of strings:
    <script setup>
    const interests = [
            {
              title: "TV",
              favorites: ["Designated Survivor",
                          "Spongebob"],
            },
            {
              title: "Games",
              favorites: ["CS:GO"],
            },
            {
              title: "Sports",
              favorites: [],
            },
          ];
    </script>
  6. In template, we loop over interests and display the title for each item in the interests array:
    <template>
      <div>
        <h1>Looping through array of objects</h1>
        <ul>
          <li v-for="(item, n) in interests" :key="n">
            {{ item.title }}
          </li>
        </ul>
      </div>
    </template>
  7. Go to https://localhost:3000 and the output of the preceding code will be as follows:
Figure 1.21 – You should now see a list of titles in the browser

Figure 1.21 – You should now see a list of titles in the browser

  1. Let’s create a second v-for loop to iterate through a favorites list for each item. Note that we use different names – fav and m – for our nested loop:
    <template>
      <div>
        <h1>Looping through array of objects</h1>
        <ul>
          <li v-for="(item, n) in interests" :key="n">
            {{ item.title }}
            <ol>
              <li v-for="(fav, m) in item.favorites"
                :key="m">
                {{ fav }}</li>
            </ol>
          </li>
        </ul>
      </div>
    </template>

Figure 1.22 displays an output where looping is performed through an array of objects:

Figure 1.22 – Nested ordered list detailing your favorites

Figure 1.22 – Nested ordered list detailing your favorites

  1. When inspecting the DOM elements (press Ctrl + F12 or open Developer Tools), you can see there are some empty elements as in Figure 1.23. This is because the Vue engine still renders the <ol> element even though favorites is an empty array:
Figure 1.23 – Displaying empty DOM elements in your virtual DOM

Figure 1.23 – Displaying empty DOM elements in your virtual DOM

  1. Now, we need to hide that empty <ol> element after applying it. We will check whether the favorites array is empty (length > 0) and then display the ordered list HTML element. Let’s add a v-if directive to <ol> with the item.favorites.length > 0 condition:
    <ol v-if="item.favorites.length > 0">
      <li v-for="(fav, m) in item.favorites" :key="m">
        {{ fav }}
      </li>
    </ol>

This won’t make a difference to the visuals of your page, but when you inspect the DOM tree in your browser, you’ll notice an HTML comment in dev mode that allows you to understand where a v-if statement might be false. When you build for production, these HTML comments won’t be visible in your DOM tree:

Figure 1.24 – Output displaying no HTML comment in production builds

Figure 1.24 – Output displaying no HTML comment in production builds

In this exercise, we have iterated through complex arrays of objects, outputting the nested keys for these objects and controlling the view state of DOM elements based on length conditions.

Next, let’s experiment with iterating through a keyed collection (or Object).

Iterating through a keyed collection (Object)

We can generally use v-for for looping through any iterative data collection type. Object in JavaScript is a key-value data collection, and we can iterate through its properties using v-for.

The syntax example is like the previous syntax example for arrays of objects and strings, with a tiny difference. Here, we change the naming convention from (item, index) to (value, key), in which key is the object’s property, and value is that key property’s value. Vue also exposes one more parameter – index – to indicate that property’s appearance index in the target object. Thus, the syntax now becomes the following:

v-for="(value, key, index) in obj"

Here, obj is our target object to iterate.

For example, assume we have the following object named course, which contains a title, a description, and the name of the lecturer(s):

<script setup>
const course = {
  title: 'Frontend development with Vue',
  description: 'Learn the awesome of Vue',
  lecturer: 'Maya and Raymond'
}
</script>

In our template, we iterate through the course’s properties and output their value in the <index>.< key > : <value> format as shown in the following code block:

<template>
  <ul>
    <li v-for="(value, key, index) in course" :key="key">
      {{index}}. {{key}}: {{value}}
    </li>
  </ul>
</template>

The output will be as shown in Figure 1.25:

Figure 1.25 – Iterating and displaying values of the course’s properties

Figure 1.25 – Iterating and displaying values of the course’s properties

Looping through the properties of an object is also a joint development practice. It is the same concept as winding through any keyed collection type, such as a hash-map (mapping according to key), lookup dictionary (it is also an object), and so on. Since the syntax stays consistent between both array and object iteration, it helps reduce the need for refactoring or data conversion.

Next, you will practice how to write basic looping for Object properties.

Exercise 1.07 – using v-for to loop through the properties of Object

In this exercise, we will be controlling a Vue data object and iterating through the properties inside of it.

To access the code file for this exercise, refer to https://github.com/PacktPublishing/Frontend-Development-Projects-with-Vue.js-3/tree/v2-edition/Chapter01/Exercise1.07.

Let’s start the exercise by performing the following steps:

  1. Use the application generated with npm init vue@3 as a starting point, or within the root folder of the code repository, navigate into the Chapter01/Exercise1.07 folder by using the following commands in order:
    > cd Chapter01/Exercise1.07/
    > yarn
  2. Run the application using the following command:
    yarn dev
  3. Open the exercise project in VS Code (by using the code . command within the project directory) or your preferred IDE.
  4. Create a new Vue component file named Exercise1-07.vue in the src/components directory.
  5. Inside Exercise1-07.vue, let’s compose information for the local data within <script setup> as follows:
    <script setup>
    const information = {
          title: "My list component information",
          subtitle: "Vue JS basics",
          items: ["Looping", "Data", "Methods"],
        }
    </script>
  6. In the <template> section, we will loop through information and display the values of its properties:
    <template>
        <div>
          <div v-for="(value, key) in information"
            :key="key">
            {{key}}: {{ value }}
          </div>
        </div>
    </template>
  7. Go to https://localhost:3000 and the output will be as follows:
Figure 1.26 – Output using v-for on the information object

Figure 1.26 – Output using v-for on the information object

  1. Note that Vue renders the value for items, which is an array of strings, the same as how we declared using JavaScript. To render it in a better format, we use the built-in JavaScript toString() function to export all the elements’ values into a string with comma separation automatically:
    <template>
        <div>
          <div v-for="(value, key) in information"
            :key="key">
            {{key}}: {{ value.toString() }}
          </div>
        </div>
    </template>
  2. The final output will render the list as follows:
Figure 1.27 – Output using v-for and toString() on values

Figure 1.27 – Output using v-for and toString() on values

Understanding iterations (or loops) is key to not only working with Vue but also with JavaScript in general. Now that we have covered how to handle loops by using the v-for directive and the importance of the key property for proper reactivity enhancement, we will explore how to use, write, and trigger methods in a component.