똑같은 삽질은 2번 하지 말자

컴포넌트의 재활용 (HOC, Mixin) 본문

Vue

컴포넌트의 재활용 (HOC, Mixin)

곽빵 2021. 6. 5. 16:46

A higher-order component (HOC) is an advanced technique in React for reusing component logic

하이오더 컴포넌트는 컴포넌트의 로직을 재사용하기 위한 고급 기술이다.

 

어떤 리스트(뉴스, 질문등등)를 보는 View들이 있는데 애네들은 기능이 완전 똑같음으로 각각의 뷰 컴포넌트를 만들지말고

컴포넌트 위에 상위 컴포넌트를 두는 느낌으로 일단 라우터에서 라우팅시 상위 컴포넌트를 씌워주기 위한 작업을 해준다.

HOC는 거의 써본적이 없으니깐 한번 코드로 구현해보면서 이해해보자.

 

router.js

    {
      path: '/news',
      name: 'news',
      component: createListView('NewsView'),
    },
    {
      path: '/ask',
      name: 'ask',
      component: createListView('AskView'),
    },
    {
      path: '/jobs',
      name: 'jobs',
      component: createListView('JobsView'),
    },
    {

createListView.js(이름과 랜더링을 해서 반환해준다.) 

import ListView from './ListView.vue';

export default function createListView(name) {
  return {
    name, // High Order Component의 이름
    render(h) {
      return h(ListView);
    },
  };
}

 

ListView.vue (랜더링 내용)

<template>
  <div>
    <list-item></list-item>
  </div>
</template>

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

export default {
  components: {
    ListItem
  },
  created() {
    this.$emit('on:progress');
    this.$store.dispatch('FETCH_LIST', this.$route.name)
      .then(() => this.$emit('off:progress'))
      .catch(() => console.log('fail'));
  }
}
</script>

<style>

</style>

 

ListItem.vue

<template>
  <ul class="news-list">
    <li v-for="news in listItems" :key="news.id" class="post">
      <div class="points">
        {{ news.points || 0 }}
      </div>
      <div>
        <p class="news-title">
          <template v-if="news.domain">
            <a :href="news.url">{{ news.title }}</a><small class="link-text" v-if="news.domain">({{ news.domain }})</small>
          </template>
          <template v-else>
            <router-link :to="`/item/${news.id}`">{{ news.title }}</router-link><small><a class="link-text" :href="news.domain" v-if="news.domain">({{ news.domain }})</a></small>
          </template>
        </p>
        <small v-if="news.user" class="link-text">
          by
          <router-link :to="`/user/${news.user}`" class="link-text">{{ news.user }}</router-link>
        </small>
        <small v-if="news.time_ago" class="link-text">
          {{ news.time_ago }}
        </small>
      </div>
    </li>
  </ul>
</template>

<script>
export default {
  computed: {
    listItems() {
      return this.$store.getters.fetchedList;
    }
  }
}
</script>

<style scoped>
.news-list {
  padding: 0;
  margin: 0;
}
.post {
  list-style: none;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #eee;
}
.points {
  width: 80px;
  height: 60px;
  color: #42b883;
  display: flex;
  align-items: center;
  justify-content: center;
}
.link-text {
  color: #828282;
}
.news-title {
  margin: 0;
}
</style>

 

이렇게 까지 하고나서 왜 이렇게하지? 솔직히 이해는 존나게 안되지만,, 일단 이렇게 상위컴포넌트를 두는걸로 코드를 줄일 수 있다고,

 내 머릿속에 집어 넣어보자

 

Mixin

믹스인은 여러 컴포넌트 간에 공통으로 사용하고 있는 로직, 기능들을 재사용하는 방법입니다.

믹스인에 정의할 수 있는 재사용 로직은 data, methods, created등과 같은 옵션들이다.

https://kr.vuejs.org/v2/guide/mixins.html

 

믹스인 — Vue.js

Vue.js - 프로그레시브 자바스크립트 프레임워크

kr.vuejs.org

하이오더컴포넌트, Mixin의 장점

두 기술의 장점은 모두 컴포넌트의 코드가 간결해지면서 코드 재활용성이 높아진다.

 

하이오더컴포넌트의 단점?

컴포넌트의 깊이가 깊어짐 -> props emit 즉, 통신하기가 꽤 까다로워 진다.

 

Mixin의 단점

여러 개를 주입했을 때 특정 코드가 어느 믹스인에서 주입된건지 확인하기가 어렵다.

 

하이오터컴포넌트와의 구조 비교

Mixin은 컴포넌트의 깊이가 깊어지지 않지만, 여려개 사용했을때 어디서 온놈인지 구별이 안된다.

 

 

Vue2 에서 믹스인을 여러개 사용하게 되면, 꽤 어려워지는데 이걸 극복하기위해 Composition API가 등장했다...

https://vue-composition-api-rfc.netlify.app/api.html#setup

 

Introduction | Vue.js

Introduction Why Composition API? Watch a free video about the Composition API on Vue Mastery Creating Vue components allows us to extract repeatable parts of the interface coupled with its functionality into reusable pieces of code. This alone can get our

v3.vuejs.org

슈벌 배워야되는게 끝나질 않는다.. 너무 행복하다

 

Comments