괴발개발

Vue.js 투두리스트 - props와 event로 리팩토링하기

debbbie 2022. 6. 6. 09:04

 

 

 

600

 

 

이전까지는 각 콤포넌트 간의 데이터 통신을 설정해주지 않아서

사용자가 페이지에서 동작을해도 화면에 바로 반영이 되지 않았다.

이번 회차부터는 data를 app.vue 파일에 한군데 묶어 동장하도록 리팩토링한다!

이전에 배웠던 props와 event를 사용하게 된다!

 

 

위의 상태에서 아래 상태로 변환하게 된다!

 

리팩토링 정리

하위 콤포넌트의 펑션은 그대로 가져와도 되지만,

인자가 제대로 들어갔는지 확인해주면 된다!

 

 


Vue.js 투두리스트 - props와 event로 리팩토링하기

2022/06/06

 

 

0.과정 요약!

입력 > 저장 > 배열 > 화면에 푸쉬

 

 

1.Todolist에 있는 기능을 Props로 만들기위해 App.vue로 옮기기

-todoList에서 입력하면 리스트 생기는 created 코드 script로 가져오기

-todoitems는 모든 파일에서 동일하게 사용하는 데이터

-App.vue에 data 추가하기 (todoItem 빈배열 추가하기

-todoList에서 가져온 코드 삭제하기

 

가져온 데이터1

  data:function(){
    return{
      todoItems:[]
    }
  },

 

가져온 데이터 2

 created: function(){
    if(localStorage.length > 0){
        for(var i =0; i <localStorage.length; i++){
          if (localStorage.key(i) !== 'loglevel:webpack-dev-server') {
          this.todoItems.push(JSON.parse(localStorage.getItem(localStorage.key(i))));
          }
        }
    }
  },

 

 

1.상위 콤포넌트(App.vue)에서 데이터를 받을 하위 콤포넌트에서 propsdata정의하기

todoList.vue. 파일 내에서 script 태그 내에 data항목 추가

 

props: ['propsdata'],

 

 

2.상위 콤포넌트인 App.vue에서 v-bind로 어떤 데이터를 내려 줄건지 정하기

-todoList태그에 v-bind 추가하기

<TodoList v-bind:propsdata="todoItems"></TodoList>

=>투두리스트 파일에 propsdata 위치로 현재 파일의 todoItems를 내려보내겠다!

 

-정보를 받아오는 위치가 달라져서 todoList파일에서 li 코드에서 in todoItems에서 propsdata로 코드 변경

 

 

<li v-for="(todoItem, index) in propsdata" v-bind:key="todoItem.item" class="shadow">

 

 

 

=>원래는 같은 todoList 파일 안에서 todoItems를 받아왔는데, 

리팩토링 과정에서 app.vue에서 props를 사용하여 이벤트를 받아오니 

값을 propsdata로 변경해야지 작동함!!!

 

 

-로컬서버에서 확인하면 똑같이 localStorage에서 작동하는걸 확인가능하다

 

 

3.App.vue에서 Input입력 내용도 가져오기

todoList.vue파일에서는 App.vue내용을 this.$emit으로 받아오기!!!

 

 

기본 구문

-상위 콤포넌트에 넣어야할 구문

v-on:하위콤포넌트 이벤트 이름= "상위 콤포넌트 메소드 이름"

 

 

-하위 콤포넌트에 넣어야할 구문

this.$emit ('이름')

 

 

App.vue의 methods에 todoOneItem이라는 메소드 추가!

=> 기존 todoInput.vue에 있었던 아이템 추가하는 코드를 App.vue로 가져온다!

methods:{
      addOneItem:function(){
        var obj = {completed: false, item: this.newTodoItem};
        localStorage.setItem(this.newTodoItem,JSON.stringify(obj));
      }
    },

 

 

 

=> 새롭게 App.vue에 넣은 this.newTodoItem은 Todolist.vue에 있으니

이것을 this.$emit으로~!

기본 구문

this.$emit('이벤트이름',인자1,인자2...)

 

 

 

-App.vue에 하위인 TodoInput에서 올라온 이벤트 추가하기

하위 콤포넌트인 Input에서 addTodoItem 메소드가 실행되고 

이것을 addOneItem이라는 App.vue상위 콤포넌트에서 받아옴!

 

<TodoInput v-on:addTodoItem="addOneItme"></TodoInput>

 

 

-methods의 addOneItem 인자 값 재설정해주기 + lnput 에 입력한 값 list로 뿌려주기 (=push)

(*이부분 체크 잘해야겠다. 보통 인자값 재설정 까지 생각못할것 같음)

 

 

=>기존

    addOneItem:function(){
        var obj = {completed: false, item: this.newTodoItem};
        localStorage.setItem(this.newTodoItem,JSON.stringify(obj));
      }

 

 

=>인자값 변경

  addOneItem:function(todoItem){
        var obj = {completed: false, item: todoItem};
        localStorage.setItem(todoItem,JSON.stringify(obj));

 

=>input 입력한 값을 push해서 화면에 보여주기

(*이미 위에서 obj 변수 정의했음으로 인자도 obj로 써주면 된다!)

(*여기서 todoItems가 아니라 todoItem으로 잘못 적어서 데이터 실시간 반영이 안되었다....바보바보바봅)

this.todoItems.push(obj);

 

 

 

input에 입력한 값이 제대로 localStorage에 저장확인 가능하다!

 

 

5.removeItem 이벤트 추가하기

 

-App.vue 파일에서 v-on:removeItem 추가하기,

기존 methods에서 removeOneItem 메소드 만들기

 

<TodoList v-bind:propsdata="todoItems" v-on:removeItem="removeOneItem"></TodoList>

 

 

-todoList에서 사용하던 removeTodo 식을 App.vue로 옮기기

(*기존에 사용하던 인자값(todoItem, index)을 넣어주기)

      removeOneItem: function(){

      }

 

 

=> 식과 인자를 제대로 넣는다면~!

 

 removeOneItem: function(todoItem, index){
        localStorage.removeItem(todoItem);
        this.todoItems.splice(index, 1);
      }

 

 

 

-TodoList.vue의 removeItem 펑션에서 this.$emit(); 추가하기

todoItem, index는 기존 인자이니 뒤에 그대로 적어주면 된다

removeTodo: function(todoItem, index){
      this.$emit('removeItem',todoItem, index);

 

 

 

-디버깅!

화면에서는 삭제를 지웠는데 localStorage에서는 왜 지워지지 않을까?

 

 

-App.vue의 remove item의 key를 지워야함

-기존 => 변경

localStorage.removeItem(todoItem);


변경하기 ===>


localStorage.removeItem(todoItem.item);

 

 

(*todoList.vue에서는 전체 값을 보내주고 => App.vue에서 item만 삭제해주면 되기때문에

todoList.vue에서는 todoItem.item으로 변경하지 않아도 된다!

 

 

-로컬 서버에서 무사히 지워지는지 확인 완료!

 

 

6.완료 상태 리팩토링하기

-App.vue에 removeOneItem 펑션 생성

-TodoList.vue에서 기존의 toggle 펑션 그래도 가져오기

(*인자!! todoItem, index 포함하기!)

 

 

    toggleComplete:function(todoItem){
      todoItem.completed =! todoItem.completed;
      localStorage.removeItem(todoItem.item);
      localStorage.setItem(todoItem.item, JSON.stringify(todoItem));
    }

 

 

 

-TodoList.vue에서 this.$emit 내용 추가

    toggleComplete:function(todoItem, index){
      this.$emit('toggleItem',todoItem, index);
    }

 

 

 

-App.vue에서 v-on으로 이벤트 추가하기

 

<TodoList v-bind:propsdata="todoItems" v-on:removeItem="removeOneItem" v-on:toggleItem="toggleOneItem"></TodoList>

 

 

 

*지난번 포스팅과 마찬가지로 인자가 (todoItem, index)로 들어가면

작동이 안되고 (todoItem)으로 들어가면 작동이 된다! 왜일까..? 대체 왜..? 이게 왜 되는거지?

 

 

 

-화면으로 확인하면 정상적으로 작동 된다

 

 

5.todoItem, App.vue 내에서 필요하다면 props, event를 여러번 

거치지 않고 바로 App.vue에서 사용가능하도록 코드 추가

 

 

기존의 코드=>

toggleOneItem: function(todoItem,index){
        todoItem.completed =! todoItem.completed;

(*위에서 기능을 방해했던 .index가 여기서는 꼭 필요하다!!! 대체 왜 ㅠㅠㅠ

위에서는 안되고 여기에서는 index가 필요한가? 개발자 친구에게 물어봐야겠다ㅠㅠ)

 

 

 

변경 코드 =>

this.todoItems[index].completed =! this.todoItems[index].completed;

 

 

둘은 같은 기능을 하지만, 훨씬 정돈된 코드로 사용 가능~!

 

 

 

7.TodoFooter에 있는 모든 아이템 삭제 리팩토링

 

-App.vue 파일에 clearAllItems 펑션 추가 + Todofooter에 있는 펑션 코드 가져오기

(*이때 인자를 가져오지 않으니 인자는 입력X)

      clearAllItems: function(){
        localStorage.clear(); 
      }

 

 

-App.vue 파일의 todolistfooter 태그에- v-on 추가

 

<TodoFooter v-on:cleaAll="clearAllItems"></TodoFooter>

 

 

-Todofooter.vue 파일의 clearTodo 메소드에 this.$emit 추가

 methods:{
    clearTodo: function(){
      this.$emit=('clearAll');
    }
  }

 

 

-화면에서 전체 삭제 확인

로컬 스토리지에서 키와 밸류값은 삭제되는데.. 화면 상에서 배열은 지우지 않아서 그대로 화면에 있다!

 

 

 

 

-로컬스토리지 전체삭제후에, 빈배열을 추가해여 화면도 같이 동기화가 된다

(*빈배열을 추가해야,, 로컬 비운후에 화면도 비워진다!!!)

clearAllItems: function(){
        localStorage.clear();
        this.todoItems = [];
      }

 

 

-화면에서 확인하기

 

 

 


[리팩토링 총정리]

1)하위 콤포넌트 데이터를 App.vue라는 상위 콤포넌트로 옮기기

2)methods에 function 작성하고 + v-on으로 데이터 연결

3)하위 콤포넌트는 this.$emot=('')으로 정리

4)한 콤포넌트를 같은 파일 내에서 사용한다면 this.로 한 파일 내에서 관리! (데이터 꼬이지 않도록!)

=> 위의 내용은 VueX의 축소판!! 땅땅~!