Vue 컴포넌트의 기초

taese0_0ng·2021년 6월 12일
2

Vue

목록 보기
2/2
post-thumbnail

컴포넌트란 무엇인가?

모든 것은 UI 컴포넌트로


웹 애플리케이션의 UI는 이를 구성하는 여러 부품의 조합으로 볼 수 있다.

웹 애플리케이션을 잘 관찰해보면 많은 UI 컴포넌트가 문구나 링크 대상등 약간만 차이를 주면 다시 사용할 수 있는 것들이다. 이렇게 재사용이 가능하다는 점이 UI 컴포넌트의 가장 중요한 측면이다.

컴포넌트의 장점과 주의할 점


장점

  • 재사용성이 향상되므로 개발 효율성이 좋아진다.
  • 이미 사용하는 컴포넌트를 재사용하므로 품질이 보장된다.
  • 적절히 분할한 컴포넌트가 느슨하게 결합하므로 유지 보수성이 향상된다.
  • 캡슐화를 통해 개발 에서 신경 써야 할 부분을 최소한으로 제한할 수 있다.

컴포넌트의 명명 규칙

// 케밥 케이스
components: {
'kebab-fruits-list':{/*...*/}
}

// 파스칼 케이스
components: {
'PascalFruitsList':{/*...*/}
}

케밥 케이스를 적용해 명명한 컴포넌트는 HTML 템플릿에서 그대로 이름을 사용한다.

<kebab-fruits-list></kebab-fruits-list>

파스칼 케이스를 적용해 명명한 컴포넌트는 HTML 템플릿에서 케밥 케이스와 파스칼 케이스 양쪽 모두의 이름을 사용할 수 있다.

<pascal-fruits-list></pascal-fruits-list>
<PascalFruitsList></PascalFruitsList>

두 가지 방법 모두 문제는 없지만, 웹 컴포넌트의 Custom Element 규격의 드래프트를 보면 하이픈으로 연결한 케밥 케이스를 기준으로 하고있다.

또한 Vue.js의 스타일 가이드에서는 여러 개의 단어로 구성된 컴포넌트 이름을 사용하는 것을 추천한다.

컴포넌트 간 통신


부모 컴포넌트에서 자식 컴포넌트로 데이터 전달하기

Vue.component(컴포넌트명, {
	props: {
		부모로부터 전달받은 속성명 : {
			type: String 혹은 Object 타입,
			default: 기본값,
			required: 필수 여부,
			validator: 유효성 검사 함수
		}
	}
	// ...template 안에서 부모로부터 전달받은 속성 사용 가능
})

부모 컴포넌트에서 자식 컴포넌트에게 props라는 객체를 전달하여 데이터를 사용할 수 있게 한다.

<child-component v-bind:item-name='myItem'></child-component>

자식컴포넌트에게 item-name이라는 props 객체를 전달한 상태이다.
child-component에서는 props로 전달받은 myItem을 본인 컴포넌트에서 item-name으로 사용가능하다.

자식 컴포넌트에서 부모 컴포넌트로 데이터 전달하기

자식 컴포넌트에서 부모 컴포넌트로 정보를 전달하려면 커스텀 이벤트를 사용한다. Vue 인스턴스에 구현된 이벤트 인터페이스는 다음과 같다.

이벤트는 v-on 디렉티브로도 처리할 수 있다.

이벤트 인터페이스

용도인터페이스
이벤트 리스닝$on(eventName)
이벤트 트리거$emit(eventName)
//자식 컴포넌트의 카운터 버튼
var counterButton = Vue.extend({
	template: '<span>{{counter}}개<button v-on:click="addToCart">추가</button></span>',
	data: function() {
		return {
			counter: 0
		}
	},
	methods: {
		addToCart: function(){
			this.counter += 1
			this.$emit('increment') //increment 커스텀 이벤트 발생
		}
	}
})

부모 컴포넌트 쪽에서는 v-on:increment로 increment 이벤트를 기다린다. 그러므로 버튼을 누르면 부모 컴포넌트의 incrementCartStatus() 메서드가 실행될 것이다.

// 부모 컴포넌트 (장바구니)
new Vue({
	el: '#fruits-counter',
	components: {
		'counter-button': counterButton
	},
	data: {
		total:0, //장바구니에 담긴 총 상품 수
		fruits: [
			{
				name:'배'
			},
			{
				name: '딸기'
			}
		]
	},
	methods: {
		incrementCartStatus: function(){
			this.total += 1
		}
	}
})
<div id="fruits-counter">
	<div v-for="fruit in fruits">
		<!-- v-on 디렉티브로 커스텀 이벤트를 탐지 -->
		{{fruit.name}}
		<counter-button v-on:increment="incrementCartStatus()"></counter-button>
	</div>
	<p>합계: {{total}}</p>
</div>

.sync 수식어

일부 경우에 속성에 "양방향 바인딩"이 필요할 수 있다.

부모 컴포넌트에서 자식 컴포넌트로 단방향 바인딩이 일반적이지만, 자식 컴포넌트에서 받은 데이터를 변화했을때, 부모 컴포넌트에서도 변화된 값으로 수정한다.

<!-- 자식컴포넌트 -->
<comp v-bind:foo.sync="bar"></comp>

<!-- 위의코드와 아래코드는 동일하다 -->
<comp :foo="bar" @update:foo="var => bar = val"></comp>

하위 컴포넌트가 foo를 갱신하려면 속성을 변경하는 대신 명시적으로 이벤트를 보내야한다.

//<comp :foo="bar" @update:foo="var => bar = val"></comp>의 경우
this.$emit('update:foo', newValue) 
profile
FrontEnd Developer #myrealtrip

0개의 댓글