DEV Community

loading...
Cover image for Create ToDo App With Vue 3 Composition API

Create ToDo App With Vue 3 Composition API

burakgur profile image Burak Gür ・2 min read

Alt Text

Hi there,
I will show you how to create todo app with composition api. Composition api is new feature to Vue.js and it's like React Hooks.

Let's build app.

1. Create new Vue 3 project with Vue CLI.

vue create-app todo-app
Enter fullscreen mode Exit fullscreen mode

2. Create form and todo list in App.vue.

<template>
    <h1>ToDo App</h1>
    <form @submit.prevent="addTodo()">
        <label>New ToDo </label>
        <input
            v-model="newTodo"
            name="newTodo"
            autocomplete="off"
        >
        <button>Add ToDo</button>
    </form>
    <h2>ToDo List</h2>
    <ul>
        <li
            v-for="(todo, index) in todos"
            :key="index"
        >
            <span
                :class="{ done: todo.done }"
                @click="doneTodo(todo)"
            >{{ todo.content }}</span>
            <button @click="removeTodo(index)">Remove</button>
        </li>
    </ul>
    <h4 v-if="todos.length === 0">Empty list.</h4>
</template>
Enter fullscreen mode Exit fullscreen mode

3. Import ref package. Takes an inner value and returns a reactive and mutable ref object.

<script>
import { ref } from 'vue';
</script>
Enter fullscreen mode Exit fullscreen mode

4. The setup function is a new component option. Create setup function.

<script>
import { ref } from 'vue';
export default {
  name: 'App',
  setup () {
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

5. Create all property and methods. Also we use localStorage for data saving.

<script>
    import { ref } from 'vue';
    export default {
        name: 'App',
        setup () {
            const newTodo = ref('');
            const defaultData = [{
                done: false,
                content: 'Write a blog post'
            }]
            const todosData = JSON.parse(localStorage.getItem('todos')) || defaultData;
            const todos = ref(todosData);
            function addTodo () {
                if (newTodo.value) {
                    todos.value.push({
                        done: false,
                        content: newTodo.value
                    });
                    newTodo.value = '';
                }
                saveData();
            }
            function doneTodo (todo) {
                todo.done = !todo.done
                saveData();
            }
            function removeTodo (index) {
                todos.value.splice(index, 1);
                saveData();
            }
            function saveData () {
                const storageData = JSON.stringify(todos.value);
                localStorage.setItem('todos', storageData);
            }
            return {
                todos,
                newTodo,
                addTodo,
                doneTodo,
                removeTodo,
                saveData
            }
        }
    }
</script>
Enter fullscreen mode Exit fullscreen mode

That's it. Also i add some SCSS code in App.vue. See demo:

Demo: https://todo-app.burakgur.vercel.app/

Repo: https://github.com/BurakGur/vue3-composition-api-todo-app

Thanks for reading 😊

Discussion (4)

pic
Editor guide
Collapse
chandragie profile image
chandragie

I haven't touched Vue 3 yet so far, that make me curious, is it the composition API or that ref package which enable you not declaring data:function(){ ... } instead just use it directly under setup() function? I don't see newTodo is declared here yet you use it as v-model.

Collapse
burakgur profile image
Burak Gür Author

Normally, we use options api with vue 2. Options api included data, mounted, created etc. functions. On the other hand, composition api is included setup function. And then setup function is included onMounted, onBeforeMount, custom methods, ref definitions, etc. We cannot use ref outside of the setup function.

Collapse
chandragie profile image
chandragie

Thanks for explaining! Gonna learn Vue 3 soon!

Collapse
madza profile image
Madza

nice and clean looking