This article explains how to set up
Vuex
in a Vue CLI 3 project. It is really helpful while you are managing user's state when authenticating a Vue application.
Steps to follow -
- Install Vuex
- Add Vuex to your application
- Creating store object and usage
- Extracting store into individual file
- Using Vuex modules
Install Vuex
First step is to install Vuex via npm or yarn
# Using npm
npm install vuex --save
# Using Yarn
yarn add vuex
Add Vuex to your application
When used with a module system, you must explicitly install Vuex via Vue.use()
//main.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
Creating store object to use in Vue App
After installing Vuex, let's create a store. It is pretty straightforward - just provide an initial state object, and some mutations:
//main.js
// Make sure to call Vue.use(Vuex) first if using a module system
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
}
});
// Make sure to inject the store in the vue instance
new Vue({
store,
render: h => h(App)
}).$mount("#app");
Due to using a single state tree, all state of our application is contained inside one big object. However, as our application grows in scale, the store can get really bloated.
Vuex allows us to divide our store into modules. Each module can contain its own state, mutations, actions, getters, and even nested modules. For any reference, please checkout this guide
Extracting store into individual file
Now create a index.js
file in src/store/index.js
and add
//index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
errors: {}
},
getters: {
errors(state) {
return state.errors;
}
},
mutations: {
SET_ERRORS(state, data) {
state.errors = data;
}
},
actions: {
setErrors({ commit }, errors) {
commit("SET_ERRORS", errors);
}
}
});
Using vuex modules
Our updated index.js
file will look like
//index.js
import Vue from "vue";
import Vuex from "vuex";
// importing a vuex module
// imporing the auth module which handles the user authentication
import auth from "./auth";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
errors: {}
},
getters: {
errors(state) {
return state.errors;
}
},
mutations: {
SET_ERRORS(state, data) {
state.errors = data;
}
},
actions: {
setErrors({ commit }, errors) {
commit("SET_ERRORS", errors);
}
},
modules: {
//registering the auth module that is imported
auth
}
});
This blog post example uses graphql
client for autenticating the users. If you are using axios
as a http client, then your vuex actions
might look different than this. The auth.js
file will look like
//auth.js
import {
LOGIN_USER_MUTATION,
GET_CURRENT_USER,
LOGOUT
} from "../graphql/queries/userQueries";
import { Apollo } from "../graphql/apollo";
export default {
namespaced: true,
state: {
token: null,
user: null
},
getters: {
authenticated(state) {
return !!state.token && !!state.user;
},
user(state) {
return state.user;
}
},
mutations: {
SET_TOKEN(state, token) {
state.token = token;
},
SET_USER(state, data) {
state.user = data;
}
},
actions: {
async login({ dispatch }, credentials) {
let response = await Apollo.mutate({
mutation: LOGIN_USER_MUTATION,
variables: {
username: credentials.email,
password: credentials.password
}
});
return dispatch("attempt", response.data.login.access_token);
},
async attempt({ commit, state }, token) {
if (token) {
localStorage.setItem("token", token);
commit("SET_TOKEN", token);
}
if (!state.token) {
return;
}
try {
let response = await Apollo.query({
query: GET_CURRENT_USER
});
commit("SET_USER", response.data.me);
Apollo.resetStore();
} catch (e) {
localStorage.removeItem("token");
commit("SET_TOKEN", null);
commit("SET_USER", null);
Apollo.resetStore();
}
},
logout({ commit }) {
return Apollo.mutate({
mutation: LOGOUT
}).then(() => {
// console.log(store);
localStorage.removeItem("token");
commit("SET_TOKEN", null);
commit("SET_USER", null);
Apollo.resetStore();
});
}
}
};
Import the file in your Vue app(main.js)
Now our updated main.js
file will look like
//main.js
import Vue from "vue";
//import the store module
import store from "@/store";
// Make sure to inject the store in the vue instance
new Vue({
store,
render: h => h(App)
}).$mount("#app");
Thatβs it! Now restart your Vue CLI project and it should all work fine. Checkout Official Vuex docs for more information.
Top comments (1)
I think this tutorial is about vue 2 not vue 3. Vue 3 uses the createApp function