To-Do app: Composition API as an alternative to Vuex
Tags: javascript, es6, vue, vue3
Published: 2020-10-10 23:21:25

---
title: To-Do app: Composition API as an alternative to Vuex
published: true
description: Provide a module that uses the new Vue 3 Composition API as an alternative to Vuex.
tags: JavaScript, es6, Vue, Vue3
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/1bvbz5su5j4knnnzu5gq.png
---

After reading an [Anthony Gore's article](https://vuejsdevelopers.com/2020/10/05/composition-api-vuex/) about using the new [Composition API](https://v3.vuejs.org/guide/composition-api-introduction.html) as some sort of replacement of Vuex, for smaller projects, I took a [simple todo app](https://codepen.io/drplepore/pen/oNLNEej/left) I built in Codepen, and then I created a new **Vue 3** app (using the vue cli) and lastly, I moved all the state and mutation methods from each component to one single file (global.js - which will be something like the store, in Vuex).

### **Source code and foreword**

Here's a list of the source code and the Codepen I will refer to in this article:

**Codepen:** <a href="https://codepen.io/drplepore/pen/oNLNEej" target="_blank">Vue To-do app</a>

**GitHub repo:** <a href="https://github.com/diegolepore/todo-app-vue3" target="_blank">todo-app-vue3</a>

**Netlify:** <a href="https://relaxed-yonath-fa8475.netlify.app/" target="_blank">https://relaxed-yonath-fa8475.netlify.app/</a>

If you take a look at the todo app I created in [Codepen](https://codepen.io/drplepore/pen/oNLNEej/left) you'll notice I'm not even using Vuex, I'm just using both [props](https://v3.vuejs.org/guide/component-props.html) to pass data down to children and [$emit](https://v3.vuejs.org/api/instance-methods.html#emit) to pass data/communicate up to parent components.

One of the advantages of the new **Composition API** is that now we have access to reactive features outside of components, which is quite powerful.

So here's what I did after creating my **Vue 3** app, and putting the components code into its own files, and basically making the app work like it is working on Codepen:


### **Move the state and mutation functions to a global file**

The first thing I did was to create the global.js file in `/src`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/w7fc07kuup581lrnnv0p.png)

Inside `global.js`, I imported the [`reactive`](https://v3.vuejs.org/api/basic-reactivity.html#reactive) and the [`readonly`](https://v3.vuejs.org/api/basic-reactivity.html#readonly) APIs. Let's take a look at the code in 'global.js' - I will add the comments in the code snippet.


```javascript
import { reactive, readonly } from "vue";

/* 
Wrapping our object with reactive() makes, 
as it clearly suggests, our object reactive 
(it even affects all nested properties).
*/

const state = reactive({
  tasks: [
     {
      id: 1,
      description: "Finish the course",
      done: false,
     }, 
     {..}, 
     {..}, 
     {..}, 
     {..}
  ],
  nextId: 6,
  tasksFiltered: [],
  activeTab: "all",
})

/* 
All these functions below are a combination of
mutations and actions (when comparing with Vuex).
But, of course, we are always free to organize our code
however we want.
*/

const filterTodos = function(filterOption) {..}

const addTodo = function(todo) {..}

const deleteTask = function(task) {..}

const toggleTaskStatus = function(task) {..}

// Export an object with the state and mutations
export default { 
  // With readonly(), we prevent our state to be mutated
  // outside of the global.js module
  state: readonly(state), 
  filterTodos, 
  addTodo, 
  deleteTask, 
  toggleTaskStatus
}
```


### **Use [Provide / inject](https://v3.vuejs.org/guide/component-provide-inject.html#provide-inject)**

Then, we need to make `global.js` (our "custom store") accesible to all of the `App.vue` child components. To do so, we have to use the `provide` property inside our `App.vue` in order to make `global.js` available to all the child components, so we import `global.js` in `App` and then, we provide it.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/d2zxiekumq10csqflo4k.png)


Right after that, in each component, we need to `inject` `global` in order to use it on each of them.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ffcjxk6yjn7r77nkgdnw.png)

Now a screenshot of each child component (but remember, you can always go to the repo and take a look a the code)

#### **TodoList.vue**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/b6s6vp0v9fxkqhntus1i.png)

#### **Form.vue**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qztuda2kqbh7km414wym.png)

#### **Header.vue**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/w7o0frrzk0sgylsbyna1.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1ucolhy57t48euexg7pp.png)


This approach can be improved, and could serve as a simpler alternative. Of course, Vuex is more debuggable and we can track mutations in the vue dev tools. So it will always depend on the project we're working on or our personal choice and point of view.

What do you think about this approach? 
Do you have any suggestions?

Hope you found this article useful! 🙂