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

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

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

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
옹재
Vue 스터디

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

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
  • HOC(High Order Component)란?
  • HOC 컴포넌트 적용
'Vue 스터디' 카테고리의 다른 글
  • React vs Vue.js 문법적 차이
  • Vue에서 virtual DOM은??
  • Vue.js 라우터 네비게이션 가드
  • Nuxt.js에서 Axios 통신
옹재
옹재

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.