Vuex with TypeScript
In this story, We will create sample To Do App using Vuex and TypeScript. Vuex is state management library + pattern for Vue applications. There are few concepts related to Vuex that we need to understand are outline below:
- Store: It is immutable central container to hold application state. The only way to change state of store is by committing mutations.
- Mutations: These are methods where we change the state of the store. We get state of store and payload - the object that we can pass from Vue components to store and perform mutations on state. Mutations are synchronous transactions. Mutations are committed using commit statement e.g.
store.commit('increment')
- Actions: Actions are used to commit mutations and can be asynchronous. Actions are also methods and receive context as parameter. Context has same methods/properties as store but context is actually not store. so, mutations are committed using
context.commit('increment')
. Actions are triggered from Vue components usingstore.dispatch('increment')
where increment is name of action - Modules: To simplify large store, Vuex allows us to divide store into modules. Each module can contain its own state, mutations, actions and even nested module.
We will have more understanding as we create store for ToDo App.
First step to use Vuex in Vue application is to install it using npm. If we used Vue CLI UI, then Vuex can be added while creating the new app itself. I would like to recommend to use Vue CLI to generate new project with TypeScript and Vuex. The sample application we are developing now would involve creating Vuex store and using it in an Vue Component.
Installation and Set up
NPM Install
npm install vuex --save
Add store.ts
file in src
folder. Add below lines to use Vuex. The Vue.use(Vuex)
is required when Vuex is used in module based systems i.e., Vuex is installed via NPM/CLI.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
Add Vuex Store
Create store.ts
, if not exists, declare Vuex Store for ToDo App as shown below.
ToDoModel.ts - the model for ToDo App is declared in src/models
folder as
We have defined store state as Array of ToDo Model. Note that we have initialized the store state using Array<ToDoModel>()
. This will create empty array of type ToDoModel. Then in mutations, we have updated store state, by push new ToDoModel item in the todos state array. Then in actions we are committing the mutations. Note that how we get payload as ToDoModel as second argument in Mutations and Actions.
ToDo Component
Now, let us design ToDo Component. First we will create component without using the store and then we will add store related functionality. This makes easy to understand what changes are required to use Vuex. Though below component seems lot of code, it is simple — we have added template, used bootstrap classes for styling, there is textbox in template for ToDo Title and one checkbox to mark it as completed. We are maintaining ToDo Array — ToDos
which is actually Getter to store and display it as ordered ToDo List.
Integrating Vuex in Vue Component
First import store
from Store.ts
that we have created for ToDo App
import store from "@/store";
Update ToDos Getter to use store
get ToDos(): ToDoModel[] {
let todos = this.$store.state.todos; //this.todos;
return todos;
}
Ensure main.ts
has store
defined
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
Similarly, to add new ToDo update addToDo method with this.$store
. We would go one step further and use promise for Async operation. We need to update action to return promise as well. This would be helpful if storing the data using HTTP call.
.dispatch("addToDo", this.model)
AddToDo() {
this.message = `Adding ${this.model.Name} to ToDo List ...`;
if (this.ToDos.some(x => x.Name == this.model.Name)) {
this.message = `ToDo item ${this.model.Name} already exists in your list`;
return;
}// this.todos.push(this.model);this.$store
.dispatch("addToDo", this.model)
.then(() => {
this.message = "ToDo added successfully to your list";
setTimeout(() => {
this.message = "";
}, 1500);
})
.catch(error => {
console.error(error);
});this.model = new ToDoModel();
}
store.ts
addToDo(context, todoModel: ToDoModel) {
return new Promise((resolve, reject) => {
context.commit('addToDo', todoModel);
resolve();
});
}
That’s all required, we implemented Vuex in our ToDo App. Now, run the app and check that ToDo List is working properly.
Thanks for reading, feel free to share and tap on clap button, if you enjoyed it.