Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Vue.js 3 By Example
Vue.js 3 By Example

Vue.js 3 By Example: Blueprints to learn Vue web development, full-stack development, and cross-platform development quickly

eBook
$20.98 $29.99
Paperback
$43.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
Table of content icon View table of contents Preview book icon Preview Book

Vue.js 3 By Example

Chapter 2: Building a Vue 3 Progressive Web App

In this chapter, we will look at how to create a GitHub progressive web app (PWA) with Vue 3. As we build the project, we will examine the inner workings of a Vue app by looking at the basic building blocks in depth. We will create Vue apps with components and, as we create them, we will look at the parts that make up a component and how they work.

We will also use more advanced features such as directives, when we need to do so. Directives let us manipulate the Document Object Model (DOM) without cluttering up a component's code. They provide us with a clean way to access DOM elements and work with them in a reusable way. This helps make testing easier and helps us to modularize our code.

Vue 3 comes with many built-in directives that we will use. In the previous chapter, we saw a brief overview of these. In this chapter, we will go into more detail to see how they work. These directives provide easy-to-use abstractions to make many things easier for us and are a basic feature of Vue 3 that we can't live without.

We will use components to display the data we want, which will take in inputs via props so that we can get the proper data and display it. In each component, we will add our own methods and make use of some component lifecycle methods. To reduce repetition of code, we use mixins to abstract out commonly used features in components and incorporate them into our components.

In this chapter, we will look at the following topics:

  • Basic theory on components and PWAs
  • Introducing the GitHub portfolio app
  • Creating the PWA
  • Serving the PWA

Technical requirements

Basic theory on components and PWAs

Before we begin with building our Vue app, let's first get familiar with components and PWA. Vue 3 lets us build frontend web apps with components. With them, we can divide our app into small, reusable parts that are composed together to make a big app. This composition is done by nesting. To make different parts of the app compose together, we can pass data between them. Components can be taken from libraries and can also be created by us.

A component consists of several parts; it includes a template, a script, and styles. The template is what is rendered on the screen. It has HyperText Markup Language (HTML) elements, directives, and components. Components and HTML elements can have props and event listeners added to them. Props are used to pass data from a parent component to a child component.

Event listeners let us listen to events emitted from a child component to a parent component. Events may be emitted with a payload, with data included in it. This enables us to have child component-to-parent component communication. With both things put together, we have a complete system to communicate between parent and child components.

Any non-trivial app will have multiple components that need to communicate with each other.

PWAs are special web apps that can be installed on the user's computer, and the browser manages these installed apps. They differ from regular web apps as they let us access some computer hardware natively. When we visit a PWA in our browsers, we can choose to install the PWA and can then reach our app from the app store.

PWAs don't require special bundling or distribution procedures. This means they are deployed just like any other web app to a server. Many modern browsers—such as Mozilla Firefox, Google Chrome, Apple Safari, and Microsoft Edge—support PWAs. This means that we can install the apps with them.

Special characteristics of PWAs include the ability to work for every user, regardless of browser choice. They are also responsive, which means they work on any device, such as desktop, laptop, tablet, or mobile devices. Initial loading is also fast since they are supposed to be cached on first load.

They are also supposed to work regardless of whether there's connectivity to the internet. Service workers run in the background to let us use PWAs offline or on low-quality networks. This is also another benefit of the caching available to PWAs.

Even though PWAs are run from the browser, they act like apps. They have app-like style interactions and navigation. Whatever is displayed is also always up to date, since the service worker runs in the background to update the data.

Security is a further important benefit of PWAs. They can only be served over HTTP Secure (HTTPS), so outsiders can't snoop on the connection. This way, we know the connection hasn't been tampered with.

Push notifications are also available with PWAs so that they can engage with the user and notify them of updates.

They can also be linked from a Uniform Resource Locator (URL), and a PWA doesn't require an installation process before we can use it—installation is strictly optional. When we install it, it provides a home screen icon on our browser so that we can click on it and start using it.

Vue 3 has a @vue/cli-plugin-pwa plugin to let us add PWA abilities into our Vue 3 project without doing any manual configuration. We just run one command and have all the files and configuration added for us automatically. With this plugin, we can develop our PWA with Vue 3, and the included service worker will run in production. Now that we have this out of the way, we are going to look at how to create reusable components.

Introducing the GitHub portfolio app

The main project of this chapter is a GitHub portfolio app. It is a PWA, which means it has all the features listed in the Basic theory on components and PWAs section of this chapter. These features are provided automatically by the @vue/cli-plugin-pwa plugin. We can add the code we need, to add the service workers and any other required configuration with one command. This way, we don't have to configure everything all by ourselves from scratch when we create our Vue project.

To get started with our app project, we will create it using Vite. We go into the folder where we want our project to be, and then run Vite to create the Vue 3 app project. To do this, we run the following commands with Node Package Manager (npm):

  1. The first command, shown in the following code snippet, runs npm to install the Vue command-line interface (CLI) globally:
    npm install -g @vue/cli@next
  2. We run the Vue CLI to create our Vue 3 project. Our project folder name is vue-example-ch2-github-app. The following command is needed to create the project folder with all the files and settings added so that we don't have to add them ourselves. This command goes to the project folder we just created and chooses the Vue 3 project when asked:
    npm vue create vue-example-ch2-github-app 
  3. Then, we run the following command to run the development server so that we can see the project in the browser and refresh the app preview when we write our code:
    npm run serve

Alternatively, we can run the following commands with Yet Another Resource Negotiator (YARN):

  1. We run yarn global add to install the Vue CLI globally, as follows:
    yarn global add @vue/cli@next
  2. To create the Vue 3 project, we run the following command and choose the Vue 3 project when asked:
    yarn create vue-example-ch2-github-app
  3. Then, we run the following command to run the development server so that we can see the project in the browser and refresh the app preview when we write our code:
    yarn serve

All the preceding commands are the same, as in they both create the project the same way; it's just a matter of which package manager we want to use to create our Vue 3 project. At this point, the project folder will have the required files for our Vue 3 project.

Our GitHub portfolio app is a progressive web app, and we can create this app easily with an existing Vue CLI plugin. Once we have created the project, we can start creating our Vue 3 PWA.

Creating the PWA

First, we need an easy way to access GitHub data via its Representational State Transfer (REST) application programming interface (API). Fortunately, an developer named Octokit has made a JavaScript client that lets us access the GitHub REST API with an access token that we create. We just need to import the package from the content distribution network (CDN) that it is served from to get access to the GitHub REST API from our browser. It also has a Node package that we can install and import. However, the Node package only supports Node.js apps, so it can't be used in our Vue 3 app.

Vue 3 is a client-side web framework, which means that it mainly runs on the browser. We shouldn't confuse packages that only run on Node with packages that support the browser, otherwise we will get errors when we use unsupported packages in the browser.

To get started, we make a few changes to the existing files. First, we remove the styling code from index.css. We are focused on the functionality of our app for this project and not so much on the styles. Also, we rename the title tag's inner text to GitHub App in the index.html file.

Then, to make our built app a PWA, we must run another command to add the service worker, to incorporate things such as hardware access support, installation, and support for offline usage. To do this, we use the @vue/cli-plugin-pwa plugin. We can add this by running the following command:

vue add pwa

This will add all the files and configurations we need to incorporate to make our Vue 3 project a PWA project.

Vue CLI creates a Vue project that uses single-file components and uses ECMAScript 6 (ES6) modules for most of our app. When we build the project, these are bundled together into files that are served on the web server and run on the browser. A project created with Vue CLI consists of main.js as its entry point, which runs all the code that is needed to create our Vue app.

Our main.js file should contain the following code:

import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
createApp(App).mount('#app')

This file is located at the root of the src folder, and Vue 3 will automatically run this when the app first loads or refreshes. The createApp function will create the Vue 3 app by passing in the entry-point component. The entry-point component is the component that is first run when we first load our app. In our project, we imported App and passed it into createApp.

Also, the index.css file is imported from the same folder. This has the global styles of our app, which is optional, so if we don't want any global styles, we can omit it. The registerServiceWorker.js file is then imported. An import with the filename only means that the code in the file is run directly, rather than us importing anything from the module.

The registerServiceWorker.js file should contain the following code:

/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
...
    offline () {
      console.log('No internet connection found. App is running          in offline mode.')
    },
    error (error) {
      console.error('Error during service worker          registration:', error)
    }
  })
}

This is what we created when we ran vue add pwa. We call the register function to register the service worker if the app is in production mode. When we run the npm run build command, the service worker will be created, and we can use the service worker that is created to let users access features—such as caching and hardware access—from the built code that we serve. The service worker is only created in production mode since we don't want anything to be cached in the development environment. We always want to see the latest data displayed so that we can create code and debug it without being confused by the caching.

One more thing we need to do is to remove the HelloWorld.vue component from the src/components folder, since we don't need this in our app. We will also remove any reference to the HelloWorld component in App.vue later.

Now that we have made the edits to the existing code files, we can create the new files. To do this, we carry out the following steps:

  1. In the components folder, we add a repo folder; and in the repo folder, we add an issue folder. In the repo folder, we add the Issues.vue component file.
  2. In the components/repo/issue folder, we add the Comments.vue file. Issues.vue is used to display the issues of a GitHub code repository. Comments.vue is used to display the comments that are added to an issue of the code repository.
  3. In the components folder itself, we add the GitHubTokenForm.vue file to let us enter and store the GitHub token.
  4. We also add the Repos.vue file to the same folder to display the code repositories of the user that the GitHub access token refers to. Then, finally, we add the User.vue file to the components folder to let us display the user information.
  5. Create a mixins folder in the src folder to add a mixin, to let us create the Octokit GitHub client with the GitHub access token.

We add the octokitMixin.js file to the mixins folder to add the empty mixin. Now, we leave them all empty, as we are ready to add the files.

Creating the GitHub client for our app

We start the project by creating the GitHub Client object that we will use throughout the app.

First, in the src/mixins/octokitMixin.js file, we add the following code:

import { Octokit } from "https://cdn.skypack.dev/@octokit/rest";
export const octokitMixin = {
  methods: {
    createOctokitClient() {
      return new Octokit({
        auth: localStorage.getItem("github-token"),
      });
    }
  }
}

The preceding file is a mixin, which is an object that we merge into components so that we can use it correctly in our components. Mixins have the same structure as components. The methods property is added so that we can create methods that we incorporate into components. To avoid naming conflicts, we should avoid naming any method with the name createOctokitClient in our components, otherwise we may get errors or behaviors that we don't expect. The createOctokitClient() method uses the Octokit client to create the client by getting the github-token local storage item and then setting that as the auth property. The auth property is our GitHub access token.

The Octokit constructor comes from the octokit-rest.min.js file that we add from https://github.com/octokit/rest.js/releases?after=v17.1.0. We find the v16.43.1 heading, click on Assets, download the octokit-rest.min.js file, and add it to the public folder. Then, in public/index.html, we add a script tag to reference the file. We should have the following code in the index.html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-
      width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <script src="<%= BASE_URL %>octokit-rest.min.js">
      </script>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.
          options.title %> doesn't work properly without 
           JavaScript enabled. Please enable it to 
            continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

Adding a display for issues and comments

Then, in the src/components/repo/issue/Comments.vue file, we add the following code:

<template>
  <div>
    <div v-if="comments.length > 0">
      <h4>Comments</h4>
      <div v-for="c of comments" :key="c.id">
        {{c.user && c.user.login}} - {{c.body}}
      </div>
    </div>
  </div>
...
        repo,
        issue_number: issueNumber,
      });
      this.comments = comments;
    }
  },
  watch: {
    owner() {
      this.getIssueComments();
    },
    repo() {
      this.getIssueComments();
    },
    issueNumber() {
      this.getIssueComments();
    }
  }
};
</script>

In this component, we have a template section and a script section. The script section has our logic to get the comments from an issue. The name property has the name of our component. We reference our component with this name in our other components, if needed. The props property has the props that the component accepts, as shown in the following code snippet:

  props: {
    owner: {
      type: String,
      required: true,
    },
    repo: {
      type: String,
      required: true,
    },
    issueNumber: {
      type: Number,
      required: true,
    },
  },

The component takes the owner, repo, and issueNumber props. We use an object to define the props so that we can validate the type easily with the type property. The type for owner and repo has the value String, so they must be strings. The issueNumber property has the type value set to Number, so it must be a number.

The required property is set to true, which means that the prop must be set when we use the Comments component in another component.

The data() method is used to return an object that has the initial values of reactive properties. The comments reactive property is set to an empty array as its initial value.

The mixins property lets us set the mixins that we want to incorporate into our app. Since octokitMixin has a methods property, whatever is inside will be added into the methods property of our component so that we can call the components directly, as we will do in the methods property of this component.

We incorporate our mixin into our component object, as follows:

mixins: [octokitMixin],

In the methods property, we have one method in our Comments component. We use the getIssueComments() method to get the comments of an issue. The code for this is shown in the following snippet:

  ...
  methods: {  
    ...
    async getIssueComments(owner, repo, issueNumber) {
      if (
        typeof owner !== "string" ||
        typeof repo !== "string" ||
        typeof issueNumber !== "number"
      ) {
        return;
      }
      const octokit = this.createOctokitClient();
      const { data: comments } = await 
        octokit.issues.listComments({
        owner,
        repo,
        issue_number: issueNumber,
      });
      this.comments = comments;
    },
    ...
  }
  ...
}

We need the owner, repo, and issueNumber properties. The owner parameter is the username of the user who owns the repository, the repo parameter is the repository name, and the issueNumber parameter is the issue number of the issue.

We check for the types of each to make sure that they are what we expect before we make a request to get the issue, with the octokit.issue.listComments() method. The Octokit client is created by the createOctokitClient() method of our mixin. The listComments() method returns a promise that resolves the issue with the comments data.

After that, we have the watch property to add our watchers. The keys of the properties are the names of the props that we are watching. Each object has an immediate property, which makes the watchers start watching as soon as the component loads. The handler methods have the handlers that are run when the prop value changes or when the component loads, since we have the immediate property set to true.

We pass in the required values from the properties of this, along with val to call the getIssueComments() method. The val parameter has the latest value of whatever prop that we are watching. This way, we always get the latest comments if we have values of all the props set.

In the template, we load the comments by referencing the comments reactive property. The values are set by the getIssueComments() method that is run in the watcher. With the v-for directive, we loop through each item and render the values. The c.user.login property has the username of the user who posted the comment, and c.body has the body of the comment.

Next, we add the following code to the src/components/Issues.vue file:

...
<script>
import { octokitMixin } from "../../mixins/octokitMixin";
import IssueComments from "./issue/Comments.vue";
export default {
  name: "RepoIssues",
  components: {
    IssueComments,
  },
  props: {
    owner: {
      type: String,
      required: true,
    },
    repo: {
      type: String,
      required: true,
    },
  },
  mixins: [octokitMixin],
  ...
};
</script>

The preceding code adds a component for displaying the issues. We have similar code in the Comments.vue component. We use the same octokitMixin mixin to incorporate the createOctokitClient() method from the mixin.

The difference is that we have the getRepoIssues() method to get the issues for a given GitHub repository instead of the comments of a given issue, and we have two props instead of three. The owner and repo props are both strings, and we make them required and validate their types in the same way.

In the data() method, we have the issues array, which is set when we call getRepoIssues. This is shown in the following code snippet:

src/components/Issues.vue

  data() {
    return {
      issues: [],
      showIssues: false,
    };
  },

The octokit.issues.listForRepo() method returns a promise that resolves the issues for a given repository. The showIssue reactive property lets us toggle whether to show the issues or not.

We also have methods to get the GitHub issues, as illustrated in the following code snippet:

src/components/Issues.vue

  methods: {
    async getRepoIssues(owner, repo) {
      const octokit = this.createOctokitClient();
      const { data: issues } = await 
        octokit.issues.listForRepo({
        owner,
        repo,
      });
      this.issues = issues;
    },
  },

The showIssues reactive property is controlled by the Show issues button. We use the v-if directive to show the issues when the showIssues reactive property is true. The outer div tag is used for checking the length property of issues so that we only show the Show issues button and the issues list when the length is greater than 0.

The method is triggered by the watchers, as follows:

src/components/Issues.vue

  watch: {
    owner: {
      handler(val) {
        this.getRepoIssues(val, this.repo);
      },
    },
    repo: {
      handler(val) {
        this.getRepoIssues(this.owner, val);
      },
    },
  },
  created () {
    this.getRepoIssues(this.owner, this.repo);
  }

In the components property, we put the IssueComments component we imported (the one we created earlier) into our component object. If we put the component in the components property, it is then registered in the component and we can use it in the template.

Next, we add the template into the file, as follows:

src/components/Issues.vue

<template>
  <div v-if="issues.length > 0">
    <button @click="showIssues = !showIssues">{{showIssues 
       ? 'Hide' : 'Show'}} issues</button>
    <div v-if="showIssues">
      <div v-for="i of issues" :key="i.id">
        <h3>{{i.title}}</h3>
        <a :href="i.url">Go to issue</a>
        <IssueComments :owner="owner" :repo="repo" 
          :issueNumber="i.number" />
      </div>
    </div>
  </div>
</template>

When we use the v-for directive, we need to include the key prop so that the entries are displayed correctly, for Vue 3 to keep track of them. The value of key must be a unique ID. We reference the IssueComments component we registered in the template and pass in the props to it. The : symbol is short for the v-bind directive, to indicate that we are passing props to a component instead of setting an attribute.

Letting users access GitHub data with a GitHub token

Next, we work on the src/components/GitHubTokenForm.vue file, as follows:

<template>
  <form @submit.prevent="saveToken">
    <div>
      <label for="githubToken">Github Token</label>
      <br />
      <input id="githubToken" v-model="githubToken" />
    </div>
    <div>
      <input type="submit" value="Save token" />
      <button type="button" @click="clearToken">Clear token
         </button>
...
    clearToken() {
      localStorage.clear();
    },
  },
};
</script>

We have a form that has an input to let us enter the GitHub access token. This way, we can save it when we submit the form. Also, we have the input, with type submit. The value attribute of it is shown as the text for the Submit button. We also have a button that lets us clear the token. The @submit.prevent directive lets us run the saveToken submit handler and call event.preventDefault() at the same time. The @ symbol is short for the v-on directive, which listens to the submit event emitted by the form.

The text input has a v-model directive to bind the input value to the githubToken reactive property. To make our input accessible for screen readers, we have a label with a for attribute that references the ID of the input. The text between the tags is displayed in the label.

Once the form is submitted, the saveToken() method runs to save the inputted value to local storage with the github-token string as the key. The created() method is a lifecycle hook that lets us get the value from local storage. The item with the github-token key is accessed to get the saved token.

The clearToken() method clears the token and is run when we click on the Clear token button.

Next, we add the following code to the src/components/Repos.vue component:

<template>
  <div>
    <h1>Repos</h1>
    <div v-for="r of repos" :key="r.id">
      <h2>{{r.owner.login}}/{{r.name}}</h2>
      <Issues :owner="r.owner.login" :repo="r.name" />
    </div>
  </div>
</template>
<script>
import Issues from "./repo/Issues.vue";
import { octokitMixin } from "../mixins/octokitMixin";
export default {
  name: "Repos",
  components: {
    Issues,
  },
  data() {
    return {
      repos: [],
    };
  },
  mixins: [octokitMixin],
  async mounted() {
    const octokit = this.createOctokitClient();
    const { data: repos } = await 
       octokit.request("/user/repos");
    this.repos = repos;
  },
};
</script>

We make a request to the /user/repos endpoint of the GitHub REST API with the octokit.request() method. Once again, the octokit object is created with the same mixin that we used before. We register the Issues component so that we can use it to display the issues of the code repository. We loop through the repos reactive property, which is assigned the values from the octokit.request() method.

The data is rendered in the template. The r.owner.login property has the username of the owner of the GitHub repository, and the r.name property has the repository name. We pass both values as props to the Issues component so that the Issues component loads the issues of the given repository.

Similarly, in the src/components/User.vue file, we write the following code:

<template>
  <div>
    <h1>User Info</h1>
    <ul>
      <li>
        <img :src="userData.avatar_url" id="avatar" />
      </li>
      <li>username: {{userData.login}}</li>
      <li>followers: {{userData.followers}}</li>
      <li>plan: {{userData.pla && userData.plan.name}}</li>
    </ul>
  </div>
...
    const { data: userData } = await 
      octokit.request("/user");
    this.userData = userData;
  },
};
</script>
<style scoped>
#avatar {
  width: 50px;
  height: 50px;
}
</style>

The scoped keyword means the styles are only applied to the current component.

This component is used to display the user information that we can access from the GitHub access token. We use the same mixin to create the octokit object for the Octokit client. The request() method is called to get the user data by making a request to the user endpoint.

Then, in the template, we show the user data by using the avatar_url property. The username.login property has the username of the owner of the token, the userData.followers property has the number of followers of the user, and the userData.plan.name property has the plan name.

Then, finally, to put the whole app together, we use the GitHubTokenForm, User, and Repo components in the App.vue component. The App.vue component is the root component that is loaded when we load the app.

In src/App.vue file, we write the following code:

<template>
  <div>
    <h1>Github App</h1>
    <GitHubTokenForm />
    <User />
    <Repos />
  </div>
</template>
<script>
import GitHubTokenForm from "./components/GitHubTokenForm.vue";
import Repos from "./components/Repos.vue";
import User from "./components/User.vue";
export default {
  name: "App",
  components: {
    GitHubTokenForm,
    Repos,
    User,
  },
};
</script>

We register all three components by putting them in the components property to register them. Then, we use all of them in the template.

Now, we should see the following screen:

Figure 2.1 – List of repositories

Figure 2.1 – List of repositories

We see a list of repositories displayed, and if there are any issues recorded for them, we see the Show issues button, which lets us see any issues for the given repository. This can be seen in the following screenshot:

Figure 2.2 – Show issues button

Figure 2.2 – Show issues button

We can click Hide issues to hide them. If there are any comments, then we should see them below the issues.

Serving the PWA

Now that we have built the app, we can serve it so that we can install it in our browser. Let's begin, as follows:

  1. To build the app, we run the following command:
    npm run build
  2. We can use the browser-sync package, which we install by running the following command:
    npm install –g browser-sync

    The preceding command will install a web server.

  3. We can go into the dist folder, which has the built files, and run browser-sync to serve the PWA.
  4. Now, to run the app, we need to get the GitHub authentication token from our GitHub account. If you don't have a GitHub account, then you will have to sign up for one.
  5. Once we have created an account, then we can get the token. To get the token, log in to your GitHub account.
  6. Go to https://github.com/settings/tokens.
  7. Once the page is loaded, click on the Personal access tokens link.
  8. Click Generate new token to generate a token. Once it's created, copy the token down somewhere so that we can use it by entering it in our app.

    We should see something like this:

    Figure 2.3 – The screen for getting the token

    Figure 2.3 – The screen for getting the token

  9. Once you have the token, go back to the app we created, which is loaded in the browser.
  10. Enter the token into the GitHub Token input, click Save token, and then refresh the page. If there are any repositories and associated issues and comments, then they should show in the page.
  11. Once we are in the browser, we should see a plus (+) sign on the right side of the URL bar. This button lets us install the PWA.
  12. Once we install it, we should see it on the home screen. We can go to the chrome://apps URL to see the app we just installed, as shown in the following screenshot:
    Figure 2.4 – The GitHub repository listing in our PWA

    Figure 2.4 – The GitHub repository listing in our PWA

  13. If you're using Chrome or any other Chromium browser such as Edge, you can press F12 to open the developer console.
  14. Click on the Application tab and then the Service Workers link on the left side to let us test the service worker, as illustrated in the following screenshot:
    Figure 2.5 – The Service Workers section of the Application tab

    Figure 2.5 – The Service Workers section of the Application tab

  15. We can check the Offline checkbox to simulate how it acts when it is offline. Checking the Update on reload will reload the app with the latest data fetched when we refresh the page. The URL should be the same as the one your app is running on. This is the service worker that is registered by our GitHub PWA.
  16. The Unregister link will unregister the service worker. It should be re-registered when we run our app again.

We are now done with creating our progressive web app with Vue 3. We can install it with browsers and then use it like any other app on our device.

Summary

By building a GitHub PWA, we learned how to create components that can be reused. We also looked at how to add props to let us pass data from a parent component to a child component. In the child component, we validate the props by checking the data type and specifying whether a prop is required. This way, we can easily see when a prop has a value that is unexpected.

We also looked at how to use watchers to watch for changes with reactive property values. Watchers can be added to watch for changes in any reactive property. We can watch the data that is being changed locally, and also the value of props. They are both reactive, so they will both trigger the watcher methods. We can run asynchronous code within a watcher, which is something that can't be done with computed properties.

Also, we had a look at lifecycle hooks of components. Each component also has its own lifecycle hooks. We can add our own code to the lifecycle methods, to run code when we want to run them. There are lifecycle hooks for all parts of a component lifecycle, including the beginning stage when it is loaded, through to when it is updated and destroyed.

Finally, we learned how to convert our Vue 3 web app into a PWA with a command-line plugin. We can add a plugin to our Vue project to create a PWA. With it, a service worker will be registered in our app to handle different connection types and caching.

In the next chapter, we will create a slider puzzle with Vue 3, with automated tests to test each part of our app.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Download complete source code for all Vue.js projects built throughout the book
  • Discover steps to build production-ready Vue.js apps across web, mobile, and desktop
  • Build a compelling portfolio of web apps, including shopping cart system, booking app, slider puzzle game, real-time chat app, and more

Description

With its huge ecosystem and wide adoption, Vue is one of the leading frameworks thanks to its ease of use when developing applications. However, it can get challenging for aspiring Vue.js developers to make sense of the ecosystem and build meaningful applications. This book will help you understand how you can leverage Vue effectively to develop impressive apps quickly using its latest version – Vue 3.0. The book takes an example-based approach to help you get to grips with the basics of Vue 3 and create a simple application by exploring features such as components and directives. You'll then enhance your app building skills by learning how to test the app with Jest and Vue Test Utils. As you advance, you'll understand how to write non-web apps with Vue 3, create cross-platform desktop apps with the Electron plugin, and build a multi-purpose mobile app with Vue and Ionic. You'll also be able to develop web apps with Vue 3 that interact well with GraphQL APIs. Finally, you'll build a chat app that performs real-time communication using Vue 3 and Laravel. By the end of this Vue.js book, you'll have developed the skills you need to build real-world apps using Vue 3 by working through a range of projects.

Who is this book for?

This book is for web developers who want to learn frontend web development with Vue 3 and use it to create professional applications. You'll also find this book useful if you're looking to create full-stack web apps with Vue.js 3.0 as the frontend. Knowledge of JavaScript programming is required to get the most out of this book.

What you will learn

  • Get to grips with Vue architecture, components, props, directives, mixins, and other advanced features
  • Understand the Vue 3 template system and use directives
  • Use third-party libraries such as Vue Router for routing and Vuex for state management
  • Create GraphQL APIs to power your Vue 3 web apps
  • Build cross-platform Vue 3 apps with Electron and Ionic
  • Make your Vue 3 apps more captivating with PrimeVue
  • Build real-time communication apps with Vue 3 as the frontend and Laravel
Estimated delivery fee Deliver to Egypt

Standard delivery 10 - 13 business days

$12.95

Premium delivery 3 - 6 business days

$34.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Apr 26, 2021
Length: 320 pages
Edition : 1st
Language : English
ISBN-13 : 9781838826345
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
Estimated delivery fee Deliver to Egypt

Standard delivery 10 - 13 business days

$12.95

Premium delivery 3 - 6 business days

$34.95
(Includes tracking information)

Product Details

Publication date : Apr 26, 2021
Length: 320 pages
Edition : 1st
Language : English
ISBN-13 : 9781838826345
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 131.97
Vue.js 3 Cookbook
$48.99
Vue.js 3 By Example
$43.99
Building Vue.js Applications with GraphQL
$38.99
Total $ 131.97 Stars icon

Table of Contents

9 Chapters
Chapter 1: Creating Your First Application in Vue 3 Chevron down icon Chevron up icon
Chapter 2: Building a Vue 3 Progressive Web App Chevron down icon Chevron up icon
Chapter 3: Building a Slider Puzzle Game with Tests Chevron down icon Chevron up icon
Chapter 4: Building a Photo Management Desktop App Chevron down icon Chevron up icon
Chapter 5: Building a Multipurpose Calculator Mobile App with Ionic Chevron down icon Chevron up icon
Chapter 6: Building a Vacation Booking App with the PrimeVue UI Framework Chevron down icon Chevron up icon
Chapter 7: Creating a Shopping Cart System with GraphQL Chevron down icon Chevron up icon
Chapter 8: Building a Chat App with Vue 3, Laravel, and Socket.IO Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.9
(16 Ratings)
5 star 31.3%
4 star 56.3%
3 star 0%
2 star 0%
1 star 12.5%
Filter icon Filter
Top Reviews

Filter reviews by




Diane L. Nov 02, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
It's unfortunate to see a few of the bad reviews on this book. In my opinion, the book is well written and the exercises are great. I guess the chief complaint some people had is that some of the content is a little confusing on some of the steps, and you don't get the outcome you expect-This might be a legitimate complaint if you're a complete newbie to using the command line, but I personally had no problems figuring out what the book was telling me what to do.Would I recommend this book to a complete computer newbie looking to learn just any language? No. But I highly recommend it to someone who (like me) knows the general ideas of Vue, and building web apps, and is looking to gain a more fundamental understanding of the code. In fact, that's the reason I give this book 5 stars- The author takes the time to explain what the code is doing after every snippet- Something I have been struggling to find with all other sorts of web tutorials and physical books.
Amazon Verified review Amazon
Sasha Aug 20, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
My experience with learning JavaScript frameworks/libraries such as Angular, React and Vue via web courses is that they teach you how to write the syntax but you’re left lost not knowing where to start with your new knowledge and what to actually build with it. This book addresses that issue very well and helps bridge that gap to get you stuck into building with Vue.js. I recommend this book for any developers looking to get extensive experience with Vue.js.My first impressions from looking at the contents was that the contents of the book had a very good gradual learning curve of project examples to build with Vue.js 3. Starting with creating your first application, then moving onto a Progressive Web App, unit testing, integrating databases and back end technologies and more advanced topics that I didn’t even think was possible using Vue such as mobile and desktop apps. There is a great variety of app examples across all areas of development.One technology that I personally would have liked to see included in the contents would be Nuxt but I understand this book is focusing on project examples to build which would affect the technologies covered and the variety available is already vast.As stated in the preface of this book and I will bring attention in my review before you buy this book: You need to know the basics of JavaScript and will need to learn basic TypeScript concepts for the mobile app chapter. Don’t have the expectation that with no prior JavaScript knowledge you’re going to be able to get a JavaScript Developer role just by reading this book. Also make sure you read the preface (because a lot tend to skip this part) to help you get setup and get the code download files.I appreciated that there was external URLs provided to download the chapters' course code. Some development books unnecessarily waste paper and ink and create large heavy books dumping large amounts of code. The code that is included in the book is formatted well and highlighted making it easy to read even when only using black ink.I found the book very clear to follow the steps. I have worked on a project using Ionic 5 with React before and the use of GenyMotion with Android Simulator mentioned in this book handled the headaches I experienced with trying to run my project in Android Simulator in the past.The most useful chapter for me was the Electron desktop app because I had never worked with this technology before being a Front End Developer. The least useful chapter for me was the chat app but only because I work with .NET and don’t have any experience with PHP.Addressing some criticism in previous reviews regarding outdated packages. It should be well known by developers that npm packages are constantly getting updated on a daily basis. Even online articles will experience this issue. We are now at Vue Version 3 after all.If you are not experienced with npm and you encounter the current release of a package installed is incompatible with any project, you can use npm install [package name]@[version number] e.g. npm install @vue/cli@4.5.13If you need to update the version number of multiple pre-installed packages at once you can change the version numbers in package.json file then use command npm install to update your node_modules folder (this will require further learning or prior experience with npm to minimise breaking changes).
Amazon Verified review Amazon
Bhaupatil Jun 07, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Superb step by step explaination with easy language. All important things are well described form scratch.project wise details are good.thank you
Amazon Verified review Amazon
laoxiao Jul 25, 2024
Full star icon Full star icon Full star icon Full star icon Full star icon 5
it's a very useful book to learn vue, but it's outdated for now, hope this can have 2nd revision soon, specifically, using composition api instead of option api
Amazon Verified review Amazon
Brendan May 26, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
If you already know the basics of web development this book has everything you need to get started with Vue.js.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela