Login form
Tags: vue, webdev, javascript, firebase
Published: 2021-04-09 06:49:48

---
title: Login form
published: true
date: 2021-04-08 7:48:00 UTC
tags: vue, webdev, javascript, firebase
series: Vue Full Application Build
canonical_url: https://hiltonmeyer.com/articles/series/pantry/10-login-form.html
---

_Code for this can be found in the [Github Branch](https://github.com/bikingbadger/pantry/tree/10-login-form)_

This form is pretty much the same as the [registration form](https://dev.to/iarehilton/register-form-k45) so could be am interesting to look at using slots and refactoring the form. But as it stands I just want to get the login working so that I can start adding ingredients and at least creating a shopping list which would be the first milestone.

_views/Login.vue_

```
<template>
  <div>
    <label for="email">Email</label>
    <input type="email" name="email" id="email" v-model="email" />
  </div>
  <div>
    <label for="password">Password</label>
    <input type="password" name="password" id="password" v-model="password" />
  </div>
  <button @click="loginUser">Login</button>
</template>

<script>
import { mapActions } from 'vuex';

export default {
  data() {
    return {
      email: '',
      password: '',
    };
  },
  methods: {
    ...mapActions('auth', ['login']),
    loginUser() {
      const userData = {
        email: this.email,
        password: this.password,
      };

      this.login(userData);
    },
  },
};
</script>

```

### Header component [#](https://hiltonmeyer.com/articles/series/pantry/10-login-form.html#header-component)

Lets connect that up with some navigation and show when the user is actually logged in. the first thing is to extract the header into a separate component that will make changes easier and keep the main `App.vue` file cleaner. I created a file in a new directory under components, `components/ui/TheHeader.vue`. This naming is in line with the style guide of naming components using multiple words and using _The_ for components that will only be used once. Read more about this guideline in the [Vue Style Guide](https://v3.vuejs.org/style-guide/#multi-word-component-names-essential)

_components/ui/TheHeader.vue_

```
<template>
  <img
    alt="App logo"
    src="https://res.cloudinary.com/hiltonmeyer-com/image/upload/v1611488325/pantry/cooking-robot_xdaw7k.png"
  />
  <div id="nav">
    <router-link to="/">Home</router-link>
    <router-link v-if="isLoggedIn" to="/ingredients"> Ingredients</router-link>
  </div>
  <div id="auth">
    <router-link v-if="!isLoggedIn" to="/login" tag="button">
      <button>Login</button>
    </router-link>
    <router-link v-if="!isLoggedIn" to="/register">
      <button>Register</button>
    </router-link>
    <button v-if="isLoggedIn" @click.prevent="logout">Logout</button>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters('auth', ['isLoggedIn']),
  },
};
</script>

```

### Routing [#](https://hiltonmeyer.com/articles/series/pantry/10-login-form.html#routing)

To get the router links working and also to show whether the user in logged in I added the login view to the vue router setup and also added another bit of state to vuex as you can see in the below files.

_router/index.js_

```
  {
    path: '/login',
    name: 'login',
    component: () => import('../views/Login.vue'),
  },

```

### Store [#](https://hiltonmeyer.com/articles/series/pantry/10-login-form.html#store)

This takes care of showing the form when the button is clicked for either the register or the login button is pressed. For keen eye's I have already added the logout button although that currently does nothing and we'll handle that in an upcoming article. The next step is to show various links and buttons based on whether the user is logged in or not. I used the `mapGetters` method of loading the getters of the vuex state which we add as follows.

`store/auth/authMutations.js` I added `isLoggedIn` state

_store/auth/authMutations.js_

```
import router from '@/router';

export default {
  authSuccess(state, user) {
    console.log(state, user);
    state.email = user.email;
    state.username = user.username;
    state.registrationError = false;
    state.isLoggedIn = true;
    state.errorMsg = '';
    router.push({ path: 'home' });
  },
  authFail(state, error) {
    state.registrationError = true;
    state.isLoggedIn = true;
    state.errorMsg = error.message;
  },
};

```

`store/auth/authIndex.js` I added `isLoggedIn` state and set it to `false` by default

_store/auth/authIndex.js_

```
import authActions from './authActions.js';
import authMutations from './authMutations';
import authGetters from './authGetters';

export default {
  namespaced: true,
  state() {
    return {
      id: 0,
      username: '',
      email: '',
      registrationError: false,
      isLoggedIn: false,
      errorMsg: '',
    };
  },
  mutations: authMutations,
  actions: authActions,
  getters: authGetters,
};

```

`store/auth/authGetters.js` returns the `isLoggedIn` state

_store/auth/authGetters.js_

```
export default {
  isLoggedIn(state) {
    return state.isLoggedIn;
  },
};

```

### Using the new component [#](https://hiltonmeyer.com/articles/series/pantry/10-login-form.html#using-the-new-component)

With this new state in place and the component extracted this leaves the `App.vue` file needing to import and use the component

_App.vue_

```
<template>
  <the-header />
  <router-view />
</template>

<script>
import TheHeader from '@/components/ui/TheHeader.vue';
export default {
  components: {
    TheHeader,
  },
};
</script>

<style>
:root {
  --clr-neutral-500: #2c3e50;

  --clr-accent-500: #00b8f0;
}

#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--clr-neutral-500);
}

img {
  display: block;
  margin: 0 auto;
}

#nav {
  padding: 30px;
  text-align: center;
}

#nav a {
  font-weight: bold;
  color: var(--clr-neutral-500);
}

#nav a.router-link-exact-active {
  color: var(--clr-accent-500);
}
</style>

```

With that the auth is almost complete. The next step will be to add a logout functionality.