일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 프로그래머스 알고리즘
- 코테스터디
- 코딩
- 개발자
- 코테준비
- 코테공부
- 1일1코테
- 코딩테스트
- 프로그래머스 레벨0
- 알고리즘스터디
- 정처기기출
- 프로그래머스 Lv.0
- 자바스크립트
- 프로그래머스 코딩테스트
- html
- 정보처리기사
- 프로그래머스코테
- next.js
- 프로그래밍
- mysql
- Redux-Toolkit
- 알고리즘문제
- js
- CSS
- 프로그래머스코딩테스트
- 알고리즘공부
- 프로그래머스
- 프로그래머스알고리즘
- next.js 에러
- 프로그래머스 코테
- Today
- Total
계발하는 개발자
[Vue.js] 컴포넌트간 공통기능 메서드를 묶는 Mixins(믹스인) 본문
뷰로 컴포넌트를 만들다보면 시간이 지날수록 관리해야 하는 컴포넌트 수가 많아지게 되는데
그러다보면 기능적으로 겹치게 되는 메서드도 생기게 마련이다.
이러한 문제를 해결해주기 위해 존재하는 게 바로 믹스인 되시겠다.
믹스인 옵션을 사용하면 컴포넌트간 중첩되는 공통 기능들을 말그대로 하나로 믹스시켜 해당 기능을 한 번만 정의하고도
컴포넌트 단에서 재사용해서 쓸 수가 있다.
이렇게 말만 하면 입 아프니까 코드를 비교해서 보자.
1. 믹스인 사용 전 문제 상황 : 컴포넌트간 메서드 기능이 중첩되는 상황
// 뷰 인스턴스
new Vue({
el: "#cont",
store,
methods: {
// 하위 컴포넌트에서 접근하기 위해 인스턴스에 등록 !!
// 세자리 콤마 함수
numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
},
// 배열데이터 순번 셋업해주는 메서드
chgList(pm) {
store.state.setNumber = pm;
},
},
// [10] 뷰컴포넌트 - 메인 섹션2 베스트상품 컴포넌트
Vue.component("mb-comp", {
template: mainData.bestarea,
methods: {
// instance 배열 순번 셋업함수 호출
setNum(val) {
return this.$root.chgList(val);
},
// instance 세자리콤마함수 호출
setComma(val) {
return this.$root.numberWithCommas(val);
},
},
// [11] 뷰컴포넌트 - 메인 섹션4 신제품 컴포넌트
Vue.component("mn-comp", {
template: mainData.newarea,
methods: {
// instance 배열 순번 셋업함수 호출
setNum2(val) {
return this.$root.chgList(val);
},
// instance 세자리콤마함수 호출
setComma2(val) {
return this.$root.numberWithCommas(val);
},
},
위에서 보다시피 처음에 믹스인을 몰랐을 때는,
#cont 라는 root 인스턴스 메서드 구역에 각각의 기능을 하는 함수를 전역 등록해놓고
이 함수를 하위 자식 컴포넌트들에서 this.$root.함수명 해서 호출하는 방식으로 사용했었다.
처음엔 좋았다. 그런데.. 문제는 컴포넌트가 많아질수록 굳이 공통 기능을 하는 다른 함수를 또 만들어 그 함수를 통해 호출했어야 됐다.
이렇다보니 일단 코드가 복잡해지고, 함수 안에서 또 다른 함수를 콜백 호출하는 것이다보니 성능적으로도 좋지 않았을 것 같다.
이 문제를 어떻게 해결할 수 있지? 구글링과 뷰 가이드문서를 다시 읽어본 끝에 믹스인이라는 컴포넌트 옵션을 알게 되었고, 이를 사용해보았다.
믹스인 사용 방법에 대해서는 가이드에서 상세한 예시와 함께 나와있어서 적용이 어렵진 않았다 :D
근데 vue2 버전에서는 믹스인이 잘 쓰였는데, vue3 버전이 업데이트 되고 난후로는 컴포지션 API 라는 게 좀더 일반적으로 쓰이는 추세인 것 같기는 하다!
2. 믹스인 사용 후 - 컴포넌트 공통 기능을 하나의 함수로 일원화
/************* 공통기능 함수 *************/
const crossMixin = {
methods: {
// 세자리 콤마찍기 함수
setComma(val) {
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
},
// 배열 순번 셋업함수
setNum(pm) {
return store.state.setNumber = pm;
},
},
};
//////////////////////////////////////////////////
// [10] 뷰컴포넌트 - 메인 섹션2 베스트상품 컴포넌트
Vue.component("mb-comp", {
template: mainData.bestarea,
mixins: [crossMixin],
},
// [11] 뷰컴포넌트 - 메인 섹션4 신제품 컴포넌트
Vue.component("mn-comp", {
template: mainData.newarea,
mixins: [crossMixin],
},
코드가 더 깔끔해지고, 해당 기능을 어디서 참조하는지가 명확해졌다.
서로 다른 컴포넌트들간에 모두 crossMixin 이라는 하나의 객체를 mixins로 참조하고 있다.
// 세자리 콤마함수 필요한 부분
<div class="btxt2">
<span class="original-price">
<em>{{setComma(a.oprice)}}</em>
<span v-if="a.oprice">원</span>
</span>
<br>
<span class="discount-price">
<em>{{setComma(a.dprice)}}</em>
<span>원</span>
</span>
<span class="percent-price" v-if="a.oprice && a.dprice">
<em>{{((a.oprice - a.dprice) / a.oprice * 100).toFixed(0)}}%</em>
</span>
</div>
// 배열 순번 셋업함수 필요한 부분
<dl class="mbtit2">
<dd v-for="(v,i) in notelnb" :key="i">
<a href="#" @click.prevent="setNum(i)">{{v}}</a>
</dd>
</dl>
crossMixin 객체를 믹스인 받았으니, 이제 출력될 컴포넌트 템플릿에서 crossMixin 객체 안의 접근할 메서드명(전달 인수) 넘겨주면 호출된다.
잘 실행된다 !!!!!!!
각각의 mb-comp와 mn-comp의 <template> 안에서 자신의 컴포넌트에 존재 하지 않는 메서드 기능을 사용해 렌더링하려 하지만 crossMixin에 해당 메서드가 정의되어있기 때문에 오류 없이 믹스인을 사용해 렌더링 되는 것을 볼 수 있다.
아래는 믹스인 관련해서 좀더 찾아서 정리한 내용이다.
# 믹스인(Mixins)
- 믹스인이란?
- 재사용이 필요한 요소들을 모아 놓은 객체를 의미하며,
- 믹스인으로 공통 관심사를 분리하여 정의하고 필요로하는 컴포넌트에서 가져다 쓸 수 있다.
- 특징1
- Mixin 은 컴포넌트 우선으로 병합된다.
- Mixin에 data 와 methods 가 정의되어있고, 같은 이름으로 컴포넌트에도 data, methods 되어있다면 중복되는 값은 어떻게 처리 될까? methods, directive, components, data 와 같이 객체 값을 요구하는 속성은 컴포넌트에 있는 요소를 우선으로 병합한다.
- Mixin 은 컴포넌트 우선으로 병합된다.
/************* 공통기능 함수 *************/
const crossMixin = {
methods: {
// 배열 순번 셋업함수
setNum(pm) {
console.log('나는 mixIn !!!')
return store.state.setNumber = pm;
},
},
};
// [10] 뷰컴포넌트 - 메인 섹션2 베스트상품 컴포넌트
Vue.component("mb-comp", {
template: mainData.bestarea,
mixins: [crossMixin],
methods: {
// 배열 순번 셋업함수
setNum(pm) {
console.log('나는 component !!!')
return store.state.setNumber = pm;
},
},
}); //////////////////// Vue 컴포넌트 ///////////////////////
콘솔을 찍고 확인해보면 Mixin의 콘솔이 아닌 컴포넌트의 콘솔이 먼저 호출된게 확인된다.
컴포넌트에 없는 data는 Mixin의 것을, 가지고 있는 data는 컴포넌트 것을 사용한다는 것을 알 수 있다.
- 특징2
- Vue에서 Mixin의 훅은 컴포넌트의 훅 이전에 호출된다.
/************* 공통기능 함수 *************/
const crossMixin = {
methods: {
// 배열 순번 셋업함수
setNum(pm) {
return store.state.setNumber = pm;
},
},
created() {
console.log("crossMixin")
}
};
// [10] 뷰컴포넌트 - 메인 섹션2 베스트상품 컴포넌트
Vue.component("mb-comp", {
template: mainData.bestarea,
mixins: [crossMixin],
created() {
console.log("mb-comp")
}
}); //////////////////// Vue 컴포넌트 ///////////////////////
- 믹스인을 사용하지 않을 경우 발생하는 문제 상황
- 기능이 같은 코드가 중복된다.
- 믹스인 동작 순서:
- 믹스인할 객체를 만든다.
- 컴포넌트에 객체를 믹스인한다.
- 나머지 부분을 구현해 완성한다.
- 믹스인을 사용함으로써 얻는 개선점
- 같은 코드를 반복하지 않고, 특정 기능을 나타내는 객체를 캡슐화해서 재사용할 수 있다.
- 유지보수 및 협업 측면에서 훌륭한 구조를 갖출 수 있다.
# 짧은 회고
어제 공통기능 함수를 묶어서 리팩토링한 회고를 포스팅했는데 이렇게 또 공통기능으로 이런 글을 쓰게 될 줄 몰랐다.
그만큼 내가 요즘 중요성을 실감하는 부분 중 하나다.
실제로 공통기능을 하는 것들끼리 잘 묶어만 놔도 동작이 훨씬 부드러워지고, 또 가독성이 좋아 유지보수도 편한 것을 볼 수 있었다. 그리고 뭣보다 내 코드가 클린코드에 가까워지고 있다는 생각에 조금씩 희망이 든다!!
어찌보면 가장 바쁜 이 시기에, 이러한 경험들을 조금씩이나마 다져나간 것은 참 값진 것 같다.
또, 이번 기회에 뷰를 쓰면서 기본적으로 제공하는 다양한 옵션들을 관심을 갖고 익혀나갈 수 있었어서 이번 뷰로 진행한 2차 프로젝트는 절대 잊지 못할 것 같단 생각이 든다.ㅎㅎ
'💻 Frontend > Vue.js' 카테고리의 다른 글
[Vue.js 시작하기] Vue Cli 설치 (0) | 2023.08.23 |
---|---|
[Vue.js] 컴포넌트 provide(제공) / inject(주입) 이해하기 (0) | 2023.08.17 |
[Vue.js] 쇼핑몰PJ/매장찾기 | 지역명 클릭시 지역 중분류 데이터 출력1 (0) | 2023.08.16 |
[Vue.js] 강제 클릭이벤트 발생 (+ DOM조작 수행시 주의사항) (0) | 2023.05.13 |
[Vue.js] 뷰 기초 - 텍스트바인딩/반복렌더링 (0) | 2023.04.23 |
dev_genie
@dev_genie
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!