모든 뷰 컴포넌트는 자체적인 데이터 범위를 가진다. 때문에 컴포넌트간 데이터를 직접 참조할 수 없다.
컴포넌트간 데이터 교환을 위해서 다음 규칙을 따라야 한다.
컴포넌트 통신 규칙이 필요한 이유
데이터의 흐름을 추적할 수 있기 때문.
상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 수 있는 컴포넌트 통신 방법.
props 속성을 사용하기 위해서는 하위 컴포넌트의 컴포넌트 내용과 상위 컴포넌트 템플릿에 각각 코드를 추가해주어야 한다.
props로 내려준 상위 컴포넌트의 데이터가 변경되면, 하위 컴포넌트에서도 변경된 값이 반영된다.
<div id="app">
<!-- <child-component v-bind:프롭스 속성명="상위 컴포넌트 데이터명"></child-component> -->
<child-component v-bind:propsdata="message"></child-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 하위 컴포넌트 : childComponent
var childComponent = {
props: ['propsdata'],
template: '<h1>{{ propsdata }}</h1>',
};
// 상위 컴포넌트 : root 컴포넌트
new Vue({
el: '#app',
components: {
'child-component': childComponent,
},
data: {
message: 'hello'
}
});
</script>
props에 특정 타입의 값을 넣고 싶은 경우에는 아래와 같이 props를 속성명을 key로, 타입을 value로 하는 오브젝트로 선언하면 된다.
이는 컴포넌트를 읽기 좋게 문서화하고, 브라우저에서 잘못된 타입이 전달된 경우에 경고를 띄워줄 수 있어 유용하다.
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
하위 컴포넌트에서 상위 컴포넌트로 통신하는 방법.
<div id="app">
<!-- <app-header v-on:하위 컴포넌트에서 발생한 이벤트명="상위 컴포넌트의 메서드명"></app-header> -->
<app-header v-on:pass="logText"></app-header>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var appHeader = {
template: '<button v-on:click="passEvent">click me</button>',
methods: {
passEvent: function () {
this.$emit('pass');
},
},
};
new Vue({
el: '#app',
components: {
'app-header': appHeader
},
methods: {
logText: function () {
console.log('hi');
},
},
});
</script>
같은 레벨에 있는 컴포넌트간의 통신은 아래 그림처럼 event를 통해 상위 컴포넌트로 값을 넘겨준 후, 상위 컴포넌트에서 props 속성을 통해 다른 하위 컴포넌트로 값을 내려주면 된다.