인프런 커뮤니티 질문&답변

devdh.cho님의 프로필 이미지
devdh.cho

작성한 질문수

Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex

TodoList 컴포넌트의 할 일 완료 기능 구현

아이콘의 경우 새로 고침해야지 checkBtnCompleted가 적용됩니다

작성

·

427

·

수정됨

1

<template>
   <div>
       <ul>
           <li v-for="(todoItem, index) in todoItems" v-bind:key="todoItem.item" class="shadow">
               <span v-on:click="toggleComplete(todoItem, index)">
                   <i class="checkBtn fas fa-check" v-bind:class="{ checkBtnCompleted: todoItem.completed }"></i>
               </span>
               <span v-bind:class="{ textCompleted: todoItem.completed }">{{ todoItem.item }}</span>
               <span class="removeBtn" v-on:click="removeTodo(todoItem, index)">
                   <i class="fas fa-trash-alt"></i>
               </span>
           </li>
       </ul>
   </div>
</template>

i 태그를 span 안에 넣은 이유는 클릭해도 아무 반응이 없어서 span 안에 넣었습니다.

completed 관련한 v-bind는 새로고침 안해도 바로 반영되는데 checkBtnCompleted 관련한 v-bind는 새로고침 해야지 체크표가 회색으로 변합니다.

어디가 문제인지 모르겠습니다

답변 1

0

템플릿 쪽의 문법의 문제보다는 자바스크립트 레벨에서의 배열 값 변경이 잘 안되는 것 같은데 코드가 어떻게 되시나요?

devdh.cho님의 프로필 이미지
devdh.cho
질문자

TodoList.vue쪽 스크립트 코드입니다.

<script>
export default {
    props: ['propsdata'],
    methods: {
        removeTodo: function (todoItem, index) {
            this.$emit('removeItem', todoItem, index)
            
        },
        toggleComplete: function (todoItem, index) {
            this.$emit('toggleItem', todoItem, index)
        }
    },
}
</script>

App.vue쪽 스크립트 코드입니다

<script>
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 {
  data: function () {
    return {
      todoItems: []
    }
  },
  methods: {
    addOneItem: function (todoItem) {
      var obj = { completed: false, item: todoItem };
      localStorage.setItem(todoItem, JSON.stringify(obj));
      this.todoItems.push(obj);
    },
    removeOneItem: function (todoItem, index) {
      localStorage.removeItem(todoItem.item);
      this.todoItems.splice(index, 1);
    },
    toggleOneItem: function (todoItem, index) {
      // todoItem.completed = !todoItem.completed;
      console.log(typeof index);
      this.todoItems[index].completed = !this.todoItems[index].completed;
      localStorage.removeItem(todoItem.item);
      localStorage.setItem(todoItem.item, JSON.stringify(todoItem));
    },
    clearAllItems: function () {
      localStorage.clear();
      this.todoItems = [];
    }
  },
  created: function () {
    if (localStorage.length > 0) {
      for (var i = 0; i < localStorage.length; i++) {
        this.todoItems.push(JSON.parse(localStorage.getItem(localStorage.key(i))));
        // this.todoItems.push(localStorage.key(i));
        // console.log(localStorage.key(i));
      } // end for
    } // end if
  }, // end created
  components: {
    'TodoHeader': TodoHeader,
    'TodoInput': TodoInput,
    'TodoList': TodoList,
    'TodoFooter': TodoFooter,
  }
}
</script>

JS 코드상으로도 문제가 없어 보이네요.. 혹시 아래 브랜치의 코드와 비교해서 다른 점이 있는지 확인해 보시겠어요? :)

https://github.com/joshua1988/vue-intermediate/tree/todo-app/components-refactoring/vue-todo/src

devdh.cho님의 프로필 이미지
devdh.cho
질문자

코드 비교 사이트를 이용해봤는데 탭 or 띄어쓰기와 같은 차이만 있고 다른건 별 차이가 없습니다.
node를 18.14.2 LTS를 쓰고 있고 웹팩이 아닌 그냥 vue create로 강의를 진행하고 있는데 이게 원인이 될 수 있을까요?

devdh.cho님의 프로필 이미지
devdh.cho

작성한 질문수

질문하기