옹재
소소한 개발 블로그
옹재
전체 방문자
오늘
어제
  • 분류 전체보기 (66)
    • 개발 관련 서적 스터디 (6)
    • 프론트엔드 스터디 (36)
      • Javascript (16)
      • Typescript (13)
    • Vue 스터디 (22)
    • 개발 관련 스터디 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • CSS
  • 프레임워크 없는 프론트엔드 개발
  • scss
  • 개발서적 스터디
  • 프론트엔드 스터디

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
옹재

소소한 개발 블로그

Vue 스터디

Vue.js 에서 HOC(High Order Component) 만들기

2021. 7. 15. 16:53
728x90
반응형

HOC(High Order Component)란?

자주 반복해서 작성하게 되는 코드를 함수화하여 재사용하는 것을 말합니다. 리액트에서는 자주 반복되는 코드를 공통화한 뒤 props로 컴포넌트를 받아 로직을 처리한 후에 컴포넌트를 리턴해주는 형식으로 많이 사용됩니다. 이러한 개념을 Vue.js에서도 비슷하게 사용할 수 있습니다.

//NewsView.vue
<template>
    <list-item></list-item>
</template>

<script>
import ListItem from '../components/ListItem.vue'
import bus from '../utils/bus.js';
export default {
    components:{
        ListItem,
    },
    created(){
        bus.$emit('start:spinner');
        this.$store.dispatch('FETCH_NEWS')
        .then(() => bus.$emit('end:spinner'))
        .catch((err) => console.log(err));
    }
}
</script>

//JobsView.vue
<template>
    <list-item></list-item>
</template>

<script>
import ListItem from '../components/ListItem.vue';
import bus from '../utils/bus.js';
export default {
    components:{
        ListItem,
    },
    created(){
        bus.$emit('start:spinner');    
        this.$store.dispatch('FETCH_JOBS')
        .then(() => bus.$emit('end:spinner'))
        .catch((err) => console.log(err));
    }
}
</script>

위의 두 소스코드는 가져오는 데이터만 다르지 그 외의 구조나 로직들은 똑같은 것을 볼 수 있습니다. 이러한 컴포넌트 위에 새로운 컴포넌트를 정의하고 공통된 로직을 모아두는 기법이라고 보면 됩니다.

img

하지만 이러한 HOC는 공통 요소를 뽑아내 코드를 재사용할 수 있다는 장점이 있지만, 많이 사용할 수록 컴포넌트의 레빌이 깊어져서 복잡해진다는 단점이 있습니다.

HOC 컴포넌트 적용

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

export default function createListView(name){
    return{
        //재사용 할 인스턴스(컴포넌트) 옵션들
        name,                                                          (1)
        created(){                                                     (2)
            bus.$emit('start:spinner');    
            this.$store.dispatch('FETCH_LIST', this.$route.name)
            .then(() => bus.$emit('end:spinner'))
            .catch((err) => console.log(err));
        },  
        render(createElement){                                         (3)
            return createElement(ListView);
        }
    }
}

공통된 로직을 처리한 후에 ListView 컴포넌트를 render해주는 형식으로 HOC를 구성하면 됩니다.

export const router = new VueRouter({
    mode: 'history',
    routes:[
        //path : url 주소, component : 페이지에 보여질 컴포넌트
        {
            path: '/',
            redirect: '/news'
        },
        {
            path: '/news',
            name : 'news',
            // component: NewsView,
            component: createListView('NewsView'),
        },
        {
            path: '/jobs',
            name : 'jobs',
            // component: JobsView,
            component: createListView('JobsView'),
        },
        {
            path: '/ask',
            name : 'ask',
            // component: AskView ,
            component: createListView('AskView'),
        },

이렇게 되면 NewsView 안에 ListView - ListItem 으로 컴포넌트 구조가 짜여지는 걸 확인할 수 있습니다. 원래 NewView 밑에 ListView 컴포넌트가 하나 더 생기기 떄문에 많이 사용할 수록 컴포넌트 구조가 깊어질 수 밖에 없습니다.

img

그럼 컴포넌트 깊이가 깊어지지 않고 공통되는 로직을 공통화할 수 없을까?에 대해 물을 수 있습니다. 그러한 부분에 대해서는 mixins라는 기술을 사용할 수 있다고 하는데 관련 내용은 다음번에 포스팅하겠습니다.

728x90
반응형

'Vue 스터디' 카테고리의 다른 글

React vs Vue.js 문법적 차이  (0) 2021.07.19
Vue에서 virtual DOM은??  (0) 2021.07.16
Vue.js 라우터 네비게이션 가드  (0) 2021.07.15
Nuxt.js에서 Axios 통신  (0) 2021.06.24
Nuxt.js 란?  (0) 2021.06.23
    'Vue 스터디' 카테고리의 다른 글
    • React vs Vue.js 문법적 차이
    • Vue에서 virtual DOM은??
    • Vue.js 라우터 네비게이션 가드
    • Nuxt.js에서 Axios 통신
    옹재
    옹재

    티스토리툴바