Create ToDo App With Nuxt 3 Composition API
Tags: javascript, vue, tutorial, opensource
Published: 2022-07-02 07:05:45

Hi there again,
Together we will develop the Nuxt 3 version of the [Create ToDo App With Vue 3 Composition API](https://dev.to/burakgur/create-todo-app-with-vue-3-composition-api-1ok7) blog post I wrote earlier.

**1. Let's create the Nuxt 3 application.**
```bash
npx nuxi init nuxt-app
cd nuxt-app
yarn install
```

**2. Install the required packages and configure its.**

```bash
yarn add -D sass sass-loader #for sass
yarn add cookie-universal-nuxt #for cookie
```

`nuxt.config.ts`
```javascript
export default defineNuxtConfig({
  modules: [
      'cookie-universal-nuxt',
  ]
})
```

**3. Create form and todo list in app.vue.**
```vue
<template>
  <h1>ToDo App</h1>
  <form @submit.prevent="addTodo()">
    <label>New ToDo </label>
    <input v-model="newTodo" name="newTodo" autocomplete="off" />
    <button @click="addTodo()">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>
```

**4. With Nuxt 3's auto import feature, we no longer need to import packages. We just need add _setup_ attribute to script tag.**
```vue
<script setup>
  // all logic code in here
</script>
```

**5. Create all property and methods. We use `$cookies` for data saving and `useHead` for meta tags. `$cookies` come from the `cookie-universal-nuxt` package and useHead comes in nuxt.**

```vue
<script setup>
const newTodo = ref('')
const defaultData = [
  {
    done: true,
    content: 'Write a blog post'
  },
  {
    done: false,
    content: 'Listen a podcast'
  }
]
const { $cookies } = useNuxtApp()
const todosData = $cookies.get('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() {
  $cookies.set('todos', todos.value)
}
useHead({
  title: 'ToDo App',
  meta: [
    {
      name: 'description',
      content: 'Nuxt 3 ToDo App with Composition API'
    }
  ]
})
</script>
```

**6. Also we add some SCSS code.**
```scss
<style lang="scss">
$border: 2px solid
  rgba(
    $color: white,
    $alpha: 0.35
  );
$size1: 6px;
$size2: 12px;
$size3: 18px;
$size4: 24px;
$size5: 48px;
$backgroundColor: #27292d;
$textColor: white;
$primaryColor: #a0a4d9;
$secondTextColor: #1f2023;
body {
  margin: 0;
  padding: 0;
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-color: $backgroundColor;
  color: $textColor;
  #__nuxt {
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
    padding: 20px;
    h1 {
      font-weight: bold;
      font-size: 28px;
      text-align: center;
    }
    form {
      display: flex;
      flex-direction: column;
      width: 100%;
      label {
        font-size: 14px;
        font-weight: bold;
      }
      input,
      button {
        height: $size5;
        box-shadow: none;
        outline: none;
        padding-left: $size2;
        padding-right: $size2;
        border-radius: $size1;
        font-size: 18px;
        margin-top: $size1;
        margin-bottom: $size2;
      }
      input {
        background-color: transparent;
        border: $border;
        color: inherit;
      }
    }
    button {
      cursor: pointer;
      background-color: $primaryColor;
      border: 1px solid $primaryColor;
      color: $secondTextColor;
      font-weight: bold;
      outline: none;
      border-radius: $size1;
    }
    h2 {
      font-size: 22px;
      border-bottom: $border;
      padding-bottom: $size1;
    }
    ul {
      padding: 10px;
      li {
        display: flex;
        justify-content: space-between;
        align-items: center;
        border: $border;
        padding: $size2 $size4;
        border-radius: $size1;
        margin-bottom: $size2;
        span {
          cursor: pointer;
        }
        .done {
          text-decoration: line-through;
        }
        button {
          font-size: $size2;
          padding: $size1;
        }
      }
    }
    h4 {
      text-align: center;
      opacity: 0.5;
      margin: 0;
    }
  }
}
</style>
```

That's it.

See demo:
####Demo: [https://nuxt3-composition-api-todo-app.vercel.app/](https://nuxt3-composition-api-todo-app.vercel.app/)

####Repo: [https://github.com/BurakGur/nuxt3-composition-api-todo-app](https://github.com/BurakGur/nuxt3-composition-api-todo-app)

####My GitHub: [https://github.com/BurakGur](https://github.com/BurakGur)

Thanks for reading 😊