Vue.js 재사용성을 높이자! Slot 외편

Minho Yoo·2022년 10월 13일
0

Vue.js

목록 보기
6/12
post-thumbnail

Vue.js 프레임워크에서 재사용성을 높일 수 있는 Slot 외의 기능들을 알아보고자 한다.

믹스인

믹스인(Mixins)은 여러 컴포넌트 간에 공통으로 사용하고 있는 로직, 기능들을 재사용하는 방법이다.
믹스인에 정의할 수 있는 재사용 로직은 data, methods, created 등과 같은 컴포넌트 옵션이다.

믹스인 코드 형식

const HelloMixins = {
  // 컴포넌트 옵션 (data, methods, created 등)
}

new vue ({
	mixins: [HelloMixins]
})

위와 같이 믹스인을 주입할 컴포넌트에 mixins 속성을 선언하고 배열 [] 안에 주입할 믹스인들을 추가한다.

믹스인 사용 예시

실제로 있을 법한 믹스인 코드 예시를 보면 웹 애플리케이션을 구현할 때 많이 사용되는 다이얼로그(모달 혹은 팝업 창)의 열기, 닫기 로직을 믹스인에 정의했다.

const DialogMixin = {
  data() {
  	return {
      dialog: false
    }
  },
  methods: {
  	showDialog() {
      this.dialog = true;
    },
    closeDialog() {
      this.dialog = false;
    }
  }
}

DialogMixin 에는 다이얼로그의 표시 상태를 나타내는 dialog 데이터와 다이얼로그를 열거나 닫는 메서드 showDialog(), closeDialog() 가 정의되어 있다.
이제 이 믹스인을 컴포넌트에 주입하는 방법은 아래와 같다.

<!-- LoginForm.vue -->
import { DialogMixin } from './mixins.js';

export default {
  // ..
  mixins: [ DialogMixin ],
  methods: {
    submitForm() {
      axios.post('login', {
        id: this.id,
        pw: this.pw
      })
      .then(() => this.closeDialog());
      .catch(err => new Error(error));
    }
  }
}

믹스인을 사용할 수준이 되면 보통은 싱글 파일 컴포넌트 체계에서 ES6를 능숙하고 사용하고 있을텐데 위의 코드는 ES6의 무듈화 문법을 이용해 믹스인을 다른 파일에서 가져와서 주입하는 코드이다.
여기서 ES6 문법은 import와 export default, promise(axios)를 말한다.
submitForm() 메서드에서 HTTP POST 요청을 보내고 나면 this.closeDialog() 로 메서드를 호출하는데 이 메서드는 믹스인에 의해 주입된 메서드이다.
따라서 LoginForm 컴포넌트에 없더라도 믹스인에 의해 사용할 수 있다.

플러그인

플러그인은 애플리케이션에서 자주 사용될만한 속성, 함수, 라이브러리 등의 사용성을 높여주는 기능이다.
뷰 라우터, 뷰엑스 등의 코어 라이브러리가 이미 뷰 플러그인 형태로 제공되고 있다.

플러그인 사용 방법

뷰로 개발하기 위한 외부 라이브러리들을 검색하다 보면 아래와 같은 코드를 마주친 적이 있을 것이다.

Vue.use(VueRouter);
Vue.use(Vuex);

여기서 Vue.use() 코드가 바로 플러그인을 설치하여 사용하는 코드이다.
플러그인을 한번 설치하고나면 뷰 인스턴스의 내부에 플러그인에 정의한 기능이 추가된다.
그리고 나면 컴포넌트 내부에서 this로 해당 기능을 편하게 접근할 수 있다.
이런 이유로 자주 사용되는 라이;브러리나 기능들은 플러그인으로 정의하여 사용하는 것이 좋다.
한 컴포넌트에서 사용할때는 플러그인보단 그 컴포넌트에 넣는것이 좋다.

플러그인 구현 방법

플러그인을 어떻게 구현할 수 있는지 코드를 통해 알아보도록 하자.

// ChartPlugin.js
import Chart from 'chartjs';

export default {
  install(Vue, options) {
    Vue.prototype.ChartJS = Chart;
  }
}

위 코드는 chartjs라는 외부 라이브러리를 npm 방식으로 프로젝트에 설치한 후 해당 라이브러리를 플로그인으로 사용하는 코드이다.
차트 라이브러리를 불러와 Chart 라는 변수에 담았고 뷰 플러그인을 설치할 때 뷰의 프로토타입 속성으로 해당 변수를 연결하는 코드이다.
따라서 아래와 같이 뷰 인스턴스를 정의하기 전에 플로그인을 설치하면 컴포넌트에서 매번 차트 라이브러리를 불러오지 않고도 사용할 수 있다.

import ChartPlugin from './ChartPlugin.js';

Vue.use(ChartPlugin);

new Vue({
  // ...
})

특정 컴포넌트에서 차트를 사용하고 싶을 때 아래와 같이 this.ChartJS로 차트를 호출한다.

<!-- Home.vue -->
export default {
  mounted() {
  	new this.ChartJS(thsi.$refs.myChart, {
      // ...
    })
  }
}

플러그인 변수명은 $_ 가 좋다.
뷰 라이브러리 내부적으로 사용하는 private 변수는 _를 사용하고 있고, 사용자에게 노출시키는 인스턴스 관련 속성은 $를 사용하고 있기 때문이다.

HOC vs Mixins

하이 오더 컴포넌트는 리액트 진영의 함수형 프로그래밍에서 기반한 컴포넌트 개발 패턴이다.
컴포넌트의 코드를 재사용하기 위한 방법이기도 하지만 캡슐화(encapsulation)과 컴포넌트 추상화를 구현하는 방법이기도 하다.
컴포넌트의 로직을 훼손하지 않고 재사용성을 최대한 끌어올리겠다는 전략이기도 하다.

HOC를 이용한 접근 방식의 예

일반적으로 HOC를 이용하여 컴포넌트를 구현하게 되면 다음과 같이 컴포넌트 관계에서 층이 하나 더 생긴다.

  • 일반: 상위 - 하위
  • HOC: 상위 - HOC - 하위

위와 같이 HOC를 이용하여 컴포넌트를 개발해 나가는 경우 상위와 하위의 컴포넌트 로직은 변경하지 않은 채 기능을 확장해 나갈 수 있다.
가장 간단한 예로는 상위 컴포넌트에 특정 이미지를 로딩하기 위한 url만 주입하고, 하위에는 그 url을 뿌리기만 하면 되는데 추가적인 로직은 HOC에서 해결하면 된다.

Mixins를 이용한 접근 방식

위와 같이 HOC를 이용한 접근 방식은 컴포넌트의 레이어를 복잡하게 만든다.
달리 말해 컴포넌트의 props, event 등을 넘겨야 하는 코드가 많아지는 것이다.
이에 비해 mixins는 문법도 간단하고 입문자에게 버거운 HOC 사고 방식을 하지 않아도 되는 이점이 있다.
물론 컴포넌트 기능 테스트 측면에서는 HOC가 mixins보다 유리하다.
관심사의 분리(sepration of concerns)라는 측면에서는 컴포넌트의 역할이 깨끗이 분리가 되면서 기능을 확장할 수 있기 때문이다.

결론

따라서, 개인의 선호도 차이겠지만 뷰에서는 mixns나 scoped slot을 최대한 활용하고 그래도 함수형 프로그래밍이나 컴포넌트 재사용성을 극대화하고 싶다면 HOC를 활용하여 컴포넌트 코드를 재활용하는 방법을 추천한다.

profile
Always happy coding 😊

0개의 댓글