Part 4 (a): Project: How to Build a To-do App with Vue.Js
Tags: webdev, javascript, vue, frontend
Published: 2023-08-25 21:01:24

In this article, you will learn how to build a Todo app with Vue.js. If you have any issues getting started with vue fundamentals, please start from the first chapter of this [series](https://dev.to/miracool/vue-made-easy-introduction-1dec). Most of what you will be learning is based on the knowledge you have acquired.

This is not a regular front-end-specific to-do app because all the features needed to help you get started on building projects will be available in this app. For example, it will feature: [authentication](), [unit testing](), [pinia state management](https://dev.to/miracool/a-comprehensive-guide-to-pinia-3bd1), [api implementation](), and the use of [composables]().


There's a bit of modification that countered my initial plan of using Vue 2 and adding an upgrade to Vue 3. I have come to realize that using the latest tools from the Vue ecosystem will not only help beginners trying to learn the latest version of Vue but also intermediates who are looking to stay up-to-date with the community.


So far, this project uses the latest versions of Pinia, Vue, and Tailwind CSS. Here is how you can get started:

## Setting Up the Project Boiler Plate:


### create project

To create a project, follow the step-by-step guide to setting up a Vue project in the [ documentation ](https://vuejs.org/guide/quick-start.html#creating-a-vue-application). Add Vitest for unit testing; this project does not support typescript, so there’s no need to add it. Add Pinia and Vue Router. Do ensure that you add all these options features.


### Install Icon Libary and Axios

Icons are important for representing some information while developing an application. Font Awesome is an icon library that is designed for this purpose. For quick installation, kindly follow the instructions on how to add this library to a Vue 2 or 3 app [here](https://fontawesome.com/docs/web/use-with/vue/).


Axios is a well-known JavaScript library for making HTTP requests. It's frequently used in Vue.js projects to interact with APIs and retrieve data. Here's how to [install](https://www.npmjs.com/package/axios) and configure Axios in your Vue project:


### Install Tailwind Css:
Tailwind CSS is a utility-first CSS framework that streamlines web development by providing a set of pre-designed, atomic-level utility classes. These classes can be directly applied to HTML elements to style and design them quickly without writing custom CSS. Tailwind CSS follows a "utility-first" philosophy, which means that instead of creating custom classes for each element, developers can compose styles by combining existing utility classes. [Here is how you can also add it to the project](https://tailwindcss.com/docs/installation)



This is how your `package.json` would look like when you have completed all installation.

`Package.json`:
```Javascript

{
  "name": "dev-project",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "test": "vitest",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
    "format": "prettier --write src/"
  },
  "dependencies": {
    "@fortawesome/fontawesome-svg-core": "^6.4.2",
    "@fortawesome/free-brands-svg-icons": "^6.4.2",
    "@fortawesome/free-regular-svg-icons": "^6.4.2",
    "@fortawesome/free-solid-svg-icons": "^6.4.2",
    "@fortawesome/vue-fontawesome": "^3.0.3",
    "axios": "^1.4.0",
    "pinia": "^2.1.4",
    "vue": "^3.3.4",
    "vue-router": "^4.2.4"
  },
  "devDependencies": {
    "@rushstack/eslint-patch": "^1.3.2",
    "@vitejs/plugin-vue": "^4.2.3",
    "@vue/eslint-config-prettier": "^8.0.0",
    "@vue/test-utils": "^2.4.1",
    "autoprefixer": "^10.4.15",
    "eslint": "^8.45.0",
    "eslint-plugin-vue": "^9.15.1",
    "jsdom": "^22.1.0",
    "postcss": "^8.4.28",
    "prettier": "^3.0.0",
    "tailwindcss": "^3.3.3",
    "vite": "^4.4.6",
    "vitest": "^0.33.0"
  }
}

```

## Setting Up a tailwind.config.js File:

One of the key features of Tailwind CSS is its ability to be customized through a configuration file called `tailwind.config.js`. This file lets you modify various aspects of Tailwind's default behavior and extend its functionality. 

If you have followed the [installation process here](https://tailwindcss.com/docs/installation), A config file for Tailwind will be added to your root folder. 

`Tailwind.config.js`:
```Javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}"
  ],
  theme: {
    screens: {
      sm: '480px',
      md: '768px',
      lg: '976px',
      xl: '1024',
      xxl: '1440px',
    },
    colors: {
      'primary': '#414066',
      'solid-varaint': '#4C6640',
      'light-variant': '#525168',
    },
    fontFamily: {
      popins: ['Poppins', 'sans-serif'],
    },
    extend: {
      borderRadius: {
        '2xl': '1rem',
        '4xl': '2rem',
      }
    },
  },
  plugins: [
    require('autoprefixer'),
  ]
}

```

This configuration is how we have customized the  Tailwind CSS based on our project needs. Here's what each part of the configuration does:

1.`content` : Specifies the files that Tailwind should scan to find used classes. In this case, it's looking for HTML, Vue, JavaScript, and TypeScript files.

2.`theme` : This section lets you customize the default styles provided by Tailwind.

- `screens` :  Defines breakpoints for responsive design. We've specified screen sizes for different breakpoints like small (sm), medium (md), large (lg), extra-large (xl), and xxl.
- `colors` : Defines custom color names and their corresponding hexadecimal values. 
- `fontFamily` : Specifies a custom font family to be used in your project, in this case, 'Poppins' with a fallback of 'sans-serif'. However, for this font to work properly we must install or search and import it from [google fonts](https://fonts.google.com/) into your main.css file. 

`src/assets/main.css`
```Javascript
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,800;1,300&family=Poppins:wght@400;500&display=swap');
@import './base.css';

@tailwind base;
@tailwind components;
@tailwind utilities;

```

- `extend` : Allows you to add or modify existing theme values. Here, you've added two additional border radius values.

3.`plugins`: This is where you can include additional plugins for your Tailwind setup. The example includes the autoprefixer plugin, which adds vendor prefixes to CSS properties.

Remember to run your build process after modifying the configuration to see the changes take effect in your project's styles.


## Designing Views for Vue Routes:

Each route corresponds to a specific `view/component` in your application. In Vue, views are typically created as Vue Single File Components (.vue files) that include the template, script, and style sections. Here's how you can create views:

1.Create a file named Login.vue in your `src/views/`  directory. This file will contain the template, script, and style for your Login view. repeat the same approach to create your Register and Dashbaord view

Login.vue
```Javascript
<template>
   <div>Login</div>
</template>

<script>

export default {
   name:'LoginView',
   components: {},
}
</script>

```

Register.vue
```Javascript
<template>
   <div>Register</div>
</template>

<script>

export default {
   name:'RegisterView',
   components: {},
}
</script>

```

Dashboard.vue
```Javascript
<template>
   <div>Dashboard</div>
</template>

<script>

export default {
   name:'DashboardView',
   components: {},
}
</script>

```

After creating view pages, we will be responsible for configuring and registering the pages for routing within our application using the Vue Router library. We accomplish this in the following steps:

`src/router/index.js`
```Javascript
import { createRouter, createWebHistory } from 'vue-router'
import Register from '../views/Register.vue';
import Login from '../views/Login.vue';
import Dashbaord from '../views/Dashboard.vue';

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: Login
    },
    {
      path: '/login',
      name: 'login',
      component: Login
    },
    {
      path: '/register',
      name: 'register',
      component: Register
    },
    {
      path: '/dashboard',
      name: 'dashboard',
      component: Dashbaord
    },
  ]
})

export default router

```

### Here is an explanation of how the routing works:


1.`Imports` :

The createRouter and createWebHistory functions are imported from the 'vue-router' package. These functions are used to create and configure the router instance.

2.`Component Imports` :

Three Vue components (Register, Login, and Dashboard) are imported. These components will be used as views for different routes in the application.

3.`Router Configuration` :

A router instance is created using the createRouter function. It takes an object with two properties: history and routes.

The history property is set to use web history mode with the base URL obtained from import.meta.env.BASE_URL.

The routes property is an array containing route objects. Each object defines a route with properties like path (URL path), name (route name), and component (associated Vue component).

4.`Route Definitions`:

Four routes are defined:
- `'/'`: Represents the home page using the Login component.
- `'/login'`: Represents the login page using the Login component.
- `'/register'`: Represents the registration page using the Register component.
- `'/dashboard'`: Represents the dashboard page using the Dashboard component.

5.`Export` :

The configured router instance is exported as the default export. This allows the router to be used throughout the application for navigation and rendering based on routes.

In essence, this code establishes the routing structure for a Vue application. When a user accesses specific routes, the associated components will be displayed, creating a seamless and organized user experience.