Nuxt 3 Composition API로 ToDo 앱 만들기

안녕하세요.
우리는 이전에 작성한 블로그 게시물의 Nuxt 3 버전을 함께 개발할 것입니다.

1. Nuxt 3 애플리케이션을 만들어 봅시다.

npx nuxi init nuxt-app
cd nuxt-app
yarn install


2. 필요한 패키지를 설치하고 구성합니다.

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

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


3. app.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. Nuxt 3의 자동 가져오기 기능을 사용하면 더 이상 패키지를 가져올 필요가 없습니다. 스크립트 태그에 설정 속성을 추가하기만 하면 됩니다.

<script setup>
  // all logic code in here
</script>


5. 모든 속성과 메서드를 만듭니다. 데이터 저장에는 $cookies를 사용하고 메타 태그에는 useHead를 사용합니다. $cookiescookie-universal-nuxt 패키지에서 가져오고 useHead는 nuxt에서 가져옵니다.

<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. 또한 일부 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>


그게 다야.

데모 보기:

데모: https://nuxt3-composition-api-todo-app.vercel.app/



레포: https://github.com/BurakGur/nuxt3-composition-api-todo-app



내 GitHub: https://github.com/BurakGur



읽어주셔서 감사합니다 😊

좋은 웹페이지 즐겨찾기