Persisting user authentication with Vuex in Vue

Netanel Basal
Frontend Weekly
Published in
4 min readFeb 6, 2017

This post assumes that you at least have some working knowledge of Vue and Redux.

What is Vuex?

Vuex is a state management pattern for Vue applications.
The basic idea behind Vuex, inspired by Flux, Redux, and The Elm Architecture.

The benefits of Vuex:

  1. Unlike other Redux implementations, you don’t need to use immutability to improve your app performance.
  2. Built in side effects management with actions. There is no reason to use third-party middleware like redux-thunk.
  3. Built in support for getters.
  4. Built in support for modules and dynamic module registration.

We are going to create a simple app that will simulate authentication.

For the simplicity, we are not going to use the vue-cli, we will write all the code in a simple javascript file that works on a plunker.

Preparations —

First, we need to include the libraries in our HTML file:

We also need the router-view component that will render our router components.

Create the Vue app —

The code is straightforward. We have two routes:

  1. The Home page that will render the Home component.
  2. The Login page that will render the Login component.

The store —

Let’s see the different pieces that make up Vuex store.

State —

The state object is a single object contains all your application level state and serves as the “single source of truth.”

In our app, we need to know if the user is logged in by checking if the user has a token in the browser local storage.

Mutations —

In Vuex mutations are the equivalents of reducers in Redux. The key difference is that you don’t have to use immutability to improve your performance.

Commits —

In Vuex commits are the equivalents of actions in Redux. The only way to change state in a Vuex store is by committing a mutation. Mutation handler functions must be synchronous.

Actions —

In Vuex the way to handle side effects ( like asynchronous operations ) is by dispatching actions. Actions commit mutations.

In our app, we have two actions:

The login action flow:

1. Commit LOGIN mutation. ( useful for showing a spinner ).
2. Returning a promise because when the operation complete we want to register a function that will redirect the user to the homepage from our component.
2. Simulate asynchronous operation with the setTimeout function. ( like HTTP request )
3. Save the JWT to local storage.
4. Commit LOGIN_SUCCESS mutation that will change the isLoggedIn state to true.
5. Resolve the promise.

The logout action flow:

1. Remove the JWT from local storage.
2. Commit LOGOUT mutation that will change the isLoggedIn state to false.

Getters —

In Vuex getters are the equivalents of selectors in Redux.

The final step is to pass the store to our Vue app:

const app = new Vue({ 
router,
store
}).$mount(‘#app’)

By providing the store option to the root instance, the store will be injected into all child components of the root and will be available on them as this.$store.

The Components —

Home component —

Main nav component —

The main-nav component is responsible for displaying our main navigation. First, we are setting a computed property as a getter from our store, every time there is a change in our isLoggedIn state, Vue will re-render the component.

Next, we are setting a logout method that will dispatch the logout action, remove the token from local storage, and commit LOGOUT mutation that will set the isLoggedIn state to false.

Quick tip: You can use Vuex helpers to make your life easier:

methods: {
...Vuex.mapActions([“logout”])}
}
getters: {
...Vuex.mapGetters([“isLoggedIn”])
}

Login component —

The Login component is a simple form with email and password. When the user submits the form, we are dispatching the login action, and when the promise is resolved, we are redirecting the user to the homepage.

Improvements:

  1. Add a spinner with the help of the pending state.
  2. Add Error handling.
  3. Add Navigation Guards.
  4. Extract this to a self-contained auth module.

You can find the final code here.

Follow me on Medium or Twitter to read more about Vue, Angular and JS!

👉 Give me some ♥️ by clicking the heart below

--

--

Netanel Basal
Frontend Weekly

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.