컴포넌트 간 통신과 유효범위
앵귤러1이나 백본(backbone.js)과 같은 초창기 자바스크립트 프레임워크에서는 한 화면을 1개의 뷰(View)로 간주했습니다. 따라서 한 화면의 데이터를 해당 화면 영역 어디서든지 호출이 가능했었습니다.
하지만 뷰(Vue.js)의 경우 컴포넌트로 화면을 구성하므로 같은 웹 페이지라도 데이터를 공유할 수 없습니다.
그 이유는 컴포넌트마다 자체적으로 고유한 유효 범위를 갖기 때문입니다. 이는 뷰 프레임워크 내부적으로 정의된 특징입니다. 따라서 각 컴포넌트의 유효 범위가 독립적이기 때문에 다른 컴포넌트의 값을 직접적으로 참조할 수가 없습니다.
...
<div id="app">
<my-component1></my-component1>
<my-component2></my-component2>
</div>
<script>
// 첫 번째 컴포넌트 내용
var cmp1 = {
template: '<div>첫 번째 지역 컴포넌트 : {{ cmp1Data }} </div>,
data: function(){
return{
cmp1Data : 100
}
}
};
//두 번째 컴포넌트 내용
var cmp2 = {
template : '<div>두 번째 지역 컴포넌트 : {{ cmp2Data }}</div>,
data : function() {
return {
cmp2Data : cmp1.data.cmp1Data
}
}
};
new Vue({
el : '#app',
//지역 컴포넌트 등록
components: {
'my-component1' : cmp1,
'my-component2' : cmp2
}
});
</script>
위 예제는 2개의 지역 컴포넌트를 등록하고 한 컴포넌트에서 다른 컴포넌트의 값을 직접 참조하는 예제입니다.
my-component2 컴포넌트 내용에서 {{ cmp2Data }}는 my-component1 컴포넌트의 data.cmp1Data를 참조하고 있습니다. 자바스크립트의 객체 참조 방식을 생각할 때 참조 값 100이 화면에 표시되어야 합니다. 하지만 {{ cmp2Data }}는 아무것도 표시되지 않을 것 입니다.
{{ cmp2Data }}에 아무값도 출력되지 않은 이유는 my-component2에서 my-component1의 값을 직접 참조할 수 없기 때문입니다. 즉 컴포넌트의 유효 범위로 인해 다른 컴포넌트의 값을 직접 접근하지 못하기 때문에 나타난 결과입니다. 이렇게 다른 컴포넌트의 값을 참조하지 못하기 때문에 생기는 특징도 있다. 뷰에서 미리 정의해 놓은 데이터 전달 방식에 따라 일관된 구조로 애플리케이션을 작성하게 되어서 개발자 개개인의 스타일대로 구성되지 않고 애플리케이션이 모두 동일한 데이터 흐름을 갖게 된다. 이렇게 되면 다른 사람의 코드를 빠르게 파악할 수 있어 협업하기에도 좋게 됩니다.
상. 하위 컴포넌트 관계
상위~하위 컴포넌트란 트리 구조에서 부모 노드, 자식 노드처럼 컴포넌트 간 관계가 부모, 자식으로 이루어진 컴포넌트를 의미한다. 지역 또는 전역 컴포넌트를 등록하면 등록된 컴포넌트는 자연스럽게 하위 컴포넌트가 된다. 그리고 하위 컴포넌트를 등록한 인스턴스는 상위 컴포넌트가 된다.
상위에서 하위 컴포넌트로 데이터 전달
props 속성
상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 때 사용하는 속성입니다. props 속성을 사용하려면 하위 컴포넌트의 속성에 정의한다.
Vue.component('child-component', {
props: ['props 속성 이름'],
});
그 다음 상위 컴포넌트의 HTML 코드에 등록된 child-component 컴포넌트 태그에 v-bind속성을 추가한다.
<child-component v-bind:props 속성 이름="상위 컴포넌트의 data속성"></child-component>
v-bind속성의 왼쪽 값으로 하위 컴포넌트에서 정의한 props속성을 넣고 오른쪽 값으로 하위 컴포넌트에 전달할 상위 컴포넌트의 data속성을 지정한다.
...
<div id="app">
<!-- 팁. 오른쪽에서 완쪽으로 속성을 읽으면 더 수월 -->
<child-component v-bind:propsdata="message"></child-component>
</div>
<script>
Vue.component('child-component', {
props: ['propsdata'],
template: '<p>{{ propsdata }}</p>',
});
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!
}
});
</script>
위 코드는 상위 컴포넌트의 message속성을 하위 컴포넌트에 props로 전달하여 메시지를 출력하는 예제입니다.
props속성을 이해하기 위해 코드를 작성한 순서대로 살펴보겠습니다.
1. new Vue로 인스턴스를 하나 생성합니다.
2. Vue.component를 이용해 하위 컴포넌트인 child-component를 등록합니다.
3. child-component의 내용에 props속성으로 propsdata를 정의
4. HTML에 컴포넌트 태그를 추가한다. <child-component>태그의 v-bind속성을 보면, v-bind:propsdata="message"는 상위 컴포넌트의 message 속성 값인 Hello, Vue! 텍스트를 하위 컴포넌트의 propsdata로 전달
5. child-component의 template속성에 정의된 <p>{{ propsdata }}</p>는 Hello, Vue!가 된다
예제 코드에서는 child-component를 전역으로 등록한 것 이외에 상위 컴포넌트를 지정하지 않았다.
그럼에도 불구하고 뷰 인스턴스 안에 마치 상위 컴포넌트가 존재하는 것처럼 하위 컴포넌트로 props를 내려보냈다.
그 이유는 컴포넌트를 등록함과 동시에 뷰 인스턴스 자체가 상위 컴포넌트가 되기 때문이다.
'JavaScript > Vue.js' 카테고리의 다른 글
Vue Router(뷰 라우터) (0) | 2021.01.09 |
---|---|
Vue Component teleport(뷰 컴포넌트 통신) - 2 (0) | 2021.01.07 |
Vue Component(뷰 컴포넌트) (0) | 2021.01.06 |
Vue Instance life cycle(뷰 인스턴스 라이프 사이클) (0) | 2021.01.05 |
뷰 인스턴스 (0) | 2021.01.05 |
댓글