[Vue] 뷰 Todo 애플리케이션 만들기 - 1 본문

Web/Vue

[Vue] 뷰 Todo 애플리케이션 만들기 - 1

미니모아 2022. 7. 18. 19:54
반응형

Do it! Vue.js 입문을 읽고 정리한 내용입니다.

To Do 애플리케이션 만들기

뷰 프로젝트 생성

vue init webpack-simple
npm install
npm run dev

컴포넌트 생성

아래와 같이 구성된 애플리케이션을 만들기 위해서

[TodoHeader]
[TodoInput]
[TodoList]
[TodoFooter]

src/components 에 각 컴포넌트 파일을 생성한다.

컴포넌트 등록

app.vue 파일에 생성한 컴포넌트들을 등록한다.

import TodoHeader from './components/TodoHeader.vue';
import TodoInput from './components/TodoInput.vue';
import TodoList from './components/TodoList.vue';
import TodoFooter from './components/TodoFooter.vue';

export default {
  components: {
    'TodoHeader': TodoHeader,
    'TodoInput' : TodoInput,
    'TodoList' : TodoList,
    'TodoFooter' : TodoFooter
  }
}

이후 컴포넌트 태그를 <div id='app'>에 추가한다.

<template>
  <div id="app">
    <TodoHeader/>
    <TodoInput/>
    <TodoList/>
    <TodoFooter/>
  </div>
</template>

컴포넌트 내용 구현하기

각 컴포넌트들은 아래의 기능을 가진다.

  • TodoHeader : 애플리케이션 이름 표시

  • TodoInput : 할 일 입력 및 추가

  • TodoList : 할 일 목록 표시 및 특정 할 일 삭제

  • TodoFooter : 할일 모두 삭제

TodoHeader

<template>
  <header>
    <h1>Todo</h1>
  </header>
</template>

<script>
export default {

}
</script>

<style scoped>
h1 {
  color : #2f3b52;
  font-weight: bold;
  margin: 2.5rem 0 1.5rem;
}
</style>

scope 속성 태그는 뷰에서 지원하는 속성으로 스타일 정의가 해당 컴포넌트에만 적용되도록한다.

##

TodoInput

input 추가하기

input 태그를 추가하고 v-model로 뷰 인스턴스에서 해당 인풋의 value를 인식할 수 있도록 연결해준다.

<template>
  <div>
    <input type="text" v-model="newTodoItem">
    <button>추가</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      newTodoItem:'',
    }
  }
}
</script>

<style scoped>
</style>

button 이벤트 추가하기

추가 버튼을 클릭했을 때 로컬스토리지에 텍스트 값을 저장하도록 이벤트를 연결해준다.

<template>
  <div>
    <input type="text" v-model="newTodoItem">
    <button @click="addTodo">추가</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      newTodoItem:'',
    }
  },
  methods: {
    addTodo() {
      if (this.newTodoItem !== "") {
        const value = this.newTodoItem && this.newTodoItem.trim();
        localStorage.setItem(value, value);
        this.clearInput();
      }
    },
    clearInput() {
      this.newTodoItem = '';
    }
  }
}
</script>

TodoList

로컬스토리에 저장된 할 일을 불러와 화면에 보여준다. 아래 단계를 거친다.

  • 로컬 스토리지 데이터르 뷰 데이터에 저장한다

  • 뷰 데이터의 아이템 개수만큼 리스트 아이템 표시

뷰 인스턴스가 생성되자마자 뷰 데이터에 접근할 수 있도록 created() 라이프 사이클 훅에서 로컬 스토리지의 데이터를 뷰데이터로 옮긴다.

export default {
  data(){
    return {
      todoItems:[],
    }
  },
  created() {
    if (localStorage.length > 0) {
      for(let i = 0; i < localStorage.length; i++) {
        this.todoItems.push(localStorage.key(i));
      }
    }
  }
}

template 단에서는 v-for 디렉티브를 이용하여 리스트를 렌더링한다.

<template>
  <section>
    <ul>
      <li v-for="todoItem in todoItems">{{todoItem}}</li>
    </ul>
  </section>
</template>

삭제 기능 추가하기

할 일을 삭제하기 위해서는 아래 단계를 거쳐야한다.

  • 선택한 할 일을 뷰에서 인식

  • 해당 데이터를 로컬 스토리지에서 삭제

  • 해당 데이터를 뷰 데이터에서 삭제

선택한 할 일을 뷰에서 인식하기

배열의 각 값을 key로 지정한 후 click 이벤트에 인자로 key와 인덱스 값을 넘긴다.

 <li v-for="(todoItem, index) in todoItems" :key="todoItem" class="shadow">   
     <i class="checkBtn fas fa-check" aria-hidden="true"></i>
        {{ todoItem }}
     <span class="removeBtn" type="button" @click="removeTodo(todoItem, index)">
         <i class="far fa-trash-alt" aria-hidden="true"></i>
     </span>
 </li>
해당 데이터를 로컬 스토리와 뷰 데이터에서 삭제하기
 methods: {
    removeTodo(todoItem, index) {
      localStorage.removeItem(todoItem);
      this.todoItems.splice(index, 1);
    }
  }

뷰 데이터 속성인 todoItems의 배열 요소를 제거하자마자 바로 뷰에서 자동으로 화면을 갱신하는데 이는 데이터 속성이 변하면 즉시 반영하는 뷰의 반응성 때문이다.

TodoFooter

모든 할 일을 삭제하는 기능을 구현한다.

<template>
  <div class="clearAllContainer">
    <span class="clearAllBtn" @click="clearTodo">Clear All</span>
  </div>
</template>

<script>
export default {
  methods: {
    clearTodo() {
      localStorage.clear();
    }
  }
}
</script>

Clear All 버튼을 눌렀을 때 로컬 스토리지의 데이터는 삭제되지만 할 일 목록에 표시되는 할 일 데이터는 제거되지 않기 때문에 브라우저를 새로고침해야만 변경 내역이 적용된다.

반응형
Comments