본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section16] 244. 코치 필터링하기

필터링 양식과 관련된 모든 마크업과 로직은 CoachesList.vue를 간단하게 유지하기 위해 별도의 컴포넌트에 포함시킬 거다.

 

span을 wrapper로 사용.

input요소에 checked로 한다.

왜냐하면 모든 필터 옵션, 즉 입련란에 처음에는 체크가 되어있고, 사용자가 필요에 따라 체크 해제하거나 체크할 수 있도록 만든다.

label에 for속성을 추가해 이 label이 frotend input을 가리키도록 하자.

라벨을 클릭해도 해당 입력이 체크되도록.

<!--CoachFilter.vue-->
<span class="filter-option">
  <input type="checkbox" id="frontend" checked />
  <label for="frontend">Frontend</label>
  <input type="checkbox" id="backend" checked />
  <label for="backend">Backend</label>
  <input type="checkbox" id="career" checked />
  <label for="career">Career</label>
</span>

 

 

이제 사용자가 checkbox를 클릭했을 때의 반응에 대한 로직이 필요하다.

script을 추가하고, data 프로퍼티를 추가해보자.

CoachFilter컴포넌트 내에서 관리해야하는 내부 데이터가 있다.

사용자가 어떤 옵션을 선택했는지를 관리해야한다.

// CoachFilter.vue
data() {
  return {
    filters: {
      frontend: true,
      backend: true,
      career: true,
    },
  };
},

 

 

그리고 이 데이터를 변경할 메서드를 추가해보자.

체크박스가 클릭될 때, 즉 변경될 경우에 setFilter가 실행되도록 하자.

이를 위해 해당 input요소에서 change이벤트를 수신대기하여, 값이 checked에서 unchecked로 바뀌거나 또는 반대로 변경될 때 setFilter를 트리거한다.

<span class="filter-option">
  <input type="checkbox" id="frontend" checked @change="setFilter" />
  <label for="frontend">Frontend</label>
  <input type="checkbox" id="backend" checked @change="setFilter" />
  <label for="backend">Backend</label>
  <input type="checkbox" id="career" checked @change="setFilter" />
  <label for="career">Career</label>
</span>

 

setFilter는 기본 event객체를 받는다. 기본 DOM이벤트에 바인딩했으므로.

 

이 이벤트로부터 두 가지 중요한 정보를 추출할 수 있다.

1) 변경된 input요소의 id.

각 입력란에 추가된 id에 액세스할 수 있다.

methods: {
  setFilter(event) {
    const inputId = event.target.id;
  },
},

 

 

2) 체크박스의 활성화 여부.

event.target.checked로 액세스해 트리거된 이벤트에 해당하는 input의 체크여부를 확인.

methods: {
  setFilter(event) {
    const inputId = event.target.id;
    const isActive = event.target.checked;
  },
},

 

 

이를 통해, updateFilters를 얻을 수 있다.

기존 데이터인 filters를 객체로 설정한다.

이 filters 데이터 옵션을 spread연산자를 이용해 새 객체를 복사해온다. 모든 프로퍼티들을 새로운 객체로 복사하고, 세 프로퍼티(frontend, backend, career) 중 하나로 오버라이드 할 거다.

오버라이드할 프로퍼티의 이름을 동적으로 설정하면 된다. inputId라는 상수로 설정한다.

이 상수는 frontend, backend, career를 포함한다.

export default {
  emits: ['change-filter'],
  data() {
    return {
      filters: {
        frontend: true,
        backend: true,
        career: true,
      },
    };
  },

methods: {
  setFilter(event) {
    const inputId = event.target.id;
    const isActive = event.target.checked;
    const updatedFilters = {
      ...this.filters,
      [inputId]: isActive //true 또는 false
    };
    this.filters = updatedFilters;
    this.$emit('change-filter', updatedFilters); //보내는건 change-filter이벤트고, updatedFilters를 전달.
  },
 }
};

 

이렇게 하면 filter를 내부적으로 관리할 수 있게 된다.

하지만 이게 다가 아니다.

CoachFilter컴포넌트를 사용하는 컴포넌트들이 필터를 인식할 수 있도록 만들어야한다.

그래서 emit이 필요하다. $emit에 커스텀 이벤트를 추가해 부모 컴포넌트로 다시 통신할 수 있게 만드는 것.

수신 대기중인 컴포넌트에 updatedFilters에 대한 정보 제공.

 

'emits'옵션을 추가해, 이 컴포넌트에서 change-filter 이벤트가 발생한다는걸 확실히 표현하면 좋다.

 

CoachesList.vue컴포넌트에서 coachFilter컴포넌트를 import한 후, 발생할 change-filter 이벤트를 수신대기했다가 setFilters메서드를 호출한다.

<!--CoachList.vue-->
<section>
  <coach-filter @change-filter="setFilters"></coach-filter>
</section>

<script>
  data() {
    return {
      activeFilters: {
        frontend: true,
        backend: true,
        career: true,
      },
    };
  },
    computed: {
    filteredCoaches() {
      const coaches = this.$store.getters['coaches/coaches']; //항상 모든코치를 반환하는것x.
      return coaches.filter((coach) => {
        if (this.activeFilters.frontend && coach.areas.includes('frontend')) {
          return true;
        }
        if (this.activeFilters.backend && coach.areas.includes('backend')) {
          return true;
        }
        if (this.activeFilters.career && coach.areas.includes('career')) {
          return true;
        }
        return false;
      });
    },
    hasCoachees() {
      return this.$store.getters['coaches/hasCoaches'];
    },
    isCoach() {
      return this.$store.getters['coaches/isCoach'];
    },
  },
  methods: {
    setFilters(updatedFilters) { //CoachFilter컴포넌트에서 emit하고 있는 데이터.
    // 이벤트를 수신하는 위치에서 이를 매개변수로 받아야 한다.
      console.log(updatedFilters); //{frontend: true, backend: true, career: false}
      this.activeFilters = updatedFilters; //activeFilters는 새로운 필터가 발생할때마다 덮어쓰여야한다.
    },
  },
</script>

 

coaches내의 모든 아이템에 대해 함수를 실행하여

전문분야가 frontend인 코치를 확인하고, 해당 조건을 충족하는 코치가 있으면 true반환.

 

Backend만 check를 하면, backend에 해당하는 coach만 필터링해서 나오게 된다.

 

 

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.