HOC (Higher Order Component)

devjune·2021년 7월 6일
0

Vue.js

목록 보기
22/36

이번 시간엔 HOC 하이 오더 컴포넌트를 알아보자.

HOC(Higher Order Component)

정의

뷰의 하이 오더 컴포넌트는 리액트의 하이 오더 컴포넌트에서 기원된 것이다.
하이 오더 컴포넌트는 컴포넌트의 로직(코드)을 재사용하기 위한 고급 기술이다.

여기서 컴포넌트의 로직이란 컴포넌트를 구성하는 Vue의 인스턴스 옵션을 의미한다.

현재 진행중인 news-app을 보면 news, ask, jobs 세 화면에서 공통점을 생각하면
1. 처음 페이지가 시작될 때 loading이 시작.
2. api에서 리스트를 불러옴.
3. loading이 끝나고 리스트를 화면에 표현.

api 주소만 다를 뿐 기능은 모두 같다. 즉, 로직이 같다는 의미다.
이렇게 같은 로직을 하나로 묶어 코드의 반복을 줄일 수 있다.

우선 반복적인 로직이 저장되는 js파일을 생성하자.

//ListView.vue
<template>
  <div>
    <list-item />
  </div>
</template>

<script>
import ListItem from '../components/ListItem.vue';

export default {
  components: {
    ListItem
  }
}
</script>

<style>

</style>

//CreateListView.js
import ListView from './ListView.vue';

export default function createListView(name) {
   render(createElement) {
     return createElement(ListView);
   }
}

createListView라는 함수를 만들고 render() 함수를 이용하여 createElement 함수를 인자로 받아 ListView를 전달한다.

위 구조를 근간 삼아 공통되는 로직을 추가하면 된다.

import ListView from './ListView.vue';
import bus from '../utils/bus.js';

export default function createListView(name) {
  return {
    name,
    created() {
      bus.$emit('start:spinner');
      this.$store.dispatch('FETCH_LIST', this.$route.name)
        .then(() => {
          console.log('fetched');
          bus.$emit('end:spinner');
        })
        .catch(err => {
          console.log(err);
        });
      bus.$emit('end:spinner');
    },
    render(createElement) {
      return createElement(ListView);
    }
  }
}

생성한 createListView.js는 route.js에서 news, ask, jobs에서 각각 지정한 component를 createListView로 변경하면 된다.

// route/index.js

import createListView from '../views/CreateListView.js';

...중략
routes: [
    {
      path: '/news',
      name: 'news',
      // component: NewsView,
      component: createListView('NewsView'),
      meta: {
        page: 1,
        type: 'lr'
      }
    },
    {
      path: '/ask',
      name: 'ask',
      // component: AskView,
      component: createListView('AskView'),
      meta: {
        page: 2,
        type: 'lr'
      }
    },
    {
      path: '/jobs',
      name: 'jobs',
      // component: JobsView,
      component: createListView('JobsView'),
      meta: {
        page: 3,
        type: 'lr'
      }
    }
  ]

출처 : Vue.js 완벽 가이드 - 실습과 리팩토링으로 배우는 실전 개념

profile
개발자준

0개의 댓글