Quick Summary:

Vue Composition API- Organized, Readable, and Understandable

Learn, explore, and build a to-do application using Vue Composition API and Vuex 4 TypeScript. Go through the step-by-step guide till the end and clone the github repository to experiment with the code-base.

Vue Composition API

Introduction

In this tutorial, we will learn Vue Composition API. You might have heard about it, but if not then don’t worry at all! We will start from the basics. For knowing Vue Composition API in a better way you must have knowledge about Options API, we will discuss that too!

I would suggest you visit my previous blog of the Vue 3 Tutorial series- How to Build To-do App with Vue 3 Typescript for setting up the basic demo project because in this tutorial we will be using the same github repository.

What is Vue Composition API?

Vue Composition API is function-based APIs that provides flexibility, improves code readability, and helps to maintain component logic. The main reason for introducing Vue Composition API was to address the limitations of Options API as the component gets larger.

Here are some of the limitations associated with Options API-

  • Ineffective patterns for reusing logic and component
  • Poor readability when component grows larger
  • Code gets complex and difficult to manage when the project size increases
  • Creates confusion and makes it difficult to use Typescript with ‘this.’

Vue Composition API vs Options API

You might have seen this image if you are learning Vue Composition API. Let’s see briefly what does it mean.

The difference in the component because of Vue Composition API

You will notice a setup() function is the major change. It comprises the component’s logic. In Options API we used to define data, methods, lifecycle, etc separately as a component option, but due to composition API, setup() function will consist of all these.

You might not understand the impact of this update until your component size grows larger. If you worked with a large project having complex component code or have to understand other developers’ code, you might understand the significance of code understandability and readability.

Vue Composition API sorts the component code and makes the logic reusable in a much better way.

Vue Composition API vs Options API

Let’s take a sample code from the Github repository: Vue 3 Typescript, which we have built in the previous blog- How to Build a To-do App with Typescript: Vue 3 Tutorial.

The One with Options API

Copy Text
export default{
 name: "Home",
 data() {
   return {
     tasks: []
   };
 },
 methods: {
   setTaskComplete(task){
     this.$store.commit("completeTask", task);
   },
   deleteTask(task) {
     this.$store.commit("deleteTask", task);
   }
 },
 mounted() {
   this.tasks = this.$store.state.tasks;
 }
};
 

We have used component options – data, methods, and mounted for splitting the component’s logic. Vue provides a total of six component options to use the logic. It might sound easy to code and manage, but once your component grows, it makes it difficult to organize and makes it harder for other developers to read and understand.

The One with Composition API

Copy Text
export default defineComponent({
 name: "Home",
 setup() {
   const tasks = ref([]); // ref is used to make the parameter reactive
   const store = useStore();  //alternative to Vue prototype of this.$store
   tasks.value = store.state.tasks;
 
   //this is the way to write methods
   const setTaskComplete = (task: Task): void => {
     store.commit(MutationType.CompleteTask, task);
   };  
   const deleteTask = (task: Task) => {
     store.commit(MutationType.DeleteTask, task);
   };
 
   // To support two-way data binding
   return {  
     tasks,
     setTaskComplete,
     deleteTask
   };
 }
});
</script>

On the contrary, you can see that the setup() function has combined all the six components together, which increases the readability and understandability of the code.

Initial Set Up: Vuex 4 TypeScript Example

Visit Vue 3 Tutorial with Typescript blog to create the vue-typescript project from scratch or click here to clone the vue-typescript-demo.

For implementing Vue Composition API with Typescript follow the below steps.

In the previous, files were written in Javascript with partial Typescript, but here we will update all the files with pure Typescript.

For integrating Vuex 4 with Typescript, we will need to update two files: store/index.js and store/mutations.js.

store/index.js

Open store/index.js and update the file with the following code.

Copy Text
import Task from "@/models/Task";
import { createStore, Store as VuexStore, CommitOptions } from "vuex";
import { Mutations, mutations } from "./mutations";
 
export const store = createStore({
 state: {
   tasks: [
     {
       name: "Demo for VueJS and TS",
       createdAt: new Date(),
       updatedAt: new Date(),
       completed: false,
     },
     {
       name: "UI design",
       createdAt: new Date(),
       updatedAt: new Date(),
       completed: false,
     },
   ] as Task[],
 },
 mutations,
 actions: {},
 modules: {},
});
 
//to make the store globally accessible
export function useStore() { 
 return store as Store; 
}
 
export type Store = Omit<VuexStore<any>, "commit"> & {
 commit<K extends keyof Mutations, P extends Parameters<Mutations[K]>[1]>(
   key: K,
   payload: P,
   options?: CommitOptions
 ): ReturnType<Mutations[K]>;
};

Explanation

  • Use the createStore() method to create Vuex store.
  • For using the store in different components export the useStore function. Thus, the complete store is accessible across our entire application. For accessing the store in the component, we need to inject it into the app. Thankfully, the Vue-CLI had already imported the entire store and passed it within the Vue instance of our application.

Moving towards mutations.

store/mutation.ts

Mutations are methods used for modifying the store state.

Mutations accept the state as its first argument and payload as the second and then update the state with the received payload.

As per the recommendation by Vuex official doc, we will use constants for the mutation types.

Open store/mutation.ts file and update it with the following code below.

Copy Text
import { MutationTree } from "vuex";
import { findIndex } from "lodash";
export enum MutationType {
 SetTask = "SET_TASKS",
 CompleteTask = "COMPLETE_TASK",
 DeleteTask = "REMOVE_TASK"
}
 
export type Mutations = {
 [MutationType.SetTask](state: any, task: any): void;
 [MutationType.CompleteTask](state: any, task: any): void;
 [MutationType.DeleteTask](state: any, task: any): void;
};
 
export const mutations: MutationTree<any> & Mutations = {
 [MutationType.SetTask](state, task) {
   state.tasks.push(task);
 },
 [MutationType.DeleteTask](state, task) {
   let taskIndex = findIndex(state.tasks, task);
   state.tasks.splice(taskIndex, ++taskIndex);
 },
 [MutationType.CompleteTask](state: any, task: any) {
   const taskIndex = findIndex(state.tasks, task);
   state.tasks[taskIndex].completed = true;
 }
};

Explanation

  • Vuex package provides a generic type- MutationTree. It is used for declaring the type of mutation tree.
  • MutationTypes enum stores all the possible names of mutations.
  • Further, declaring a contract (types) for every MutationType. Create a variable named mutations for storing all the implemented mutations. The MutationTree < State > & Mutations ensures that the type is implemented correctly for avoiding Typescript errors.

Implement Components with Vue Composition API

Implementing component API in the files – AddTask.vue and Home.vue. For that, you need to modify the code within < script > < script / >

AddTask.vue

Copy Text
<script lang="ts">
import { defineComponent, ref } from "vue";
import Task from "@/models/Task";
import { useStore } from "@/store";
import { MutationType } from "@/store/mutations";
import { useRouter } from "vue-router";
 
export default defineComponent({
 name: "AddTask",
 setup() {
   const taskName = ref("");
   const router = useRouter(); // Substitute of Vue prototype this.$router
   const store = useStore();
   const addTask = (): void => {
     const newTask = new Task(taskName.value);
     store.commit(MutationType.SetTask, newTask);
     taskName.value = "";
     router.push({ path: "/" });
   };
   return { taskName, addTask };
 }
});
</script>

What’s happening in this component?

  • As the name suggests, it is used for adding new tasks to the to-do list.
  • Whenever the user clicks the button Add Task, the addTask function commits the SetTask mutation which will add the newly added task to the existing tasks list.
  • Once done, the UI is updated.

Home.vue

Copy Text
<script lang="ts">
import { defineComponent, ref } from "vue";
import Task from "@/models/Task";
import { useStore } from "@/store";
import { MutationType } from "@/store/mutations";
 
export default defineComponent({
 name: "Home",
 setup() {
   const tasks = ref([]);
   const store = useStore();
   tasks.value = store.state.tasks;
   const setTaskComplete = (task: Task): void => {
     store.commit(MutationType.CompleteTask, task);
   };
   const deleteTask = (task: Task) => {
     store.commit(MutationType.DeleteTask, task);
   };
 
   return {
     tasks,
     setTaskComplete,
     deleteTask
   };
 }
});
</script>

What’s happening in this component?

  • The component is responsible for displaying and updating (marking it done or deleting it) the to-do list.
  • Whenever the user clicks the tick button, MutationType CompleteTask is triggered with an argument task, for marking the task as done.
  • Whenever the user clicks the tick button, MutationType DeleteTask is triggered with an argument task, for deleting the task as done.
  • Once done, the UI is updated.

Tutorial Takeaway

● Vuex 4 + Typescript
● Implement Vue Composition API + Typescript
● Source code- Github Repository

Conclusion

We have mostly used the major feature releases of Vuex 4 and integrated it with the Composition API in Vue 3 to develop a small demo app. With the practical implementation, we have explored the theoretical side of Composition API and seen how it is different than Options API.

I hope you’ve learned a great deal from the tutorial. If you have any suggestions or questions please feel free to comment below.

Visit the VueJS Tutorials page for more such tutorials.

If you are looking for skilled and experienced VueJS developers, get in contact with Bacancy, one of the leading Vue.js development company. If you don’t believe so, connect now and experience the best vujs development services by yourself today!

Hire Vue.js Developer

Connect Now

Get In Touch

[email protected]

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.