티스토리 뷰

반응형

컴포넌트 간 통신과 유효 범위

뷰는 컴포넌트로 화면을 구성 =>  같은 웹 페이지라도 데이터를 공유할 수 없음

- 컴포넌트 마다 자체적으로 고유한 유효범위를 갖기 때문

- 뷰 프레임워크 내부적으로 정의된 특징

- 각 컴포넌트의 유효 범위가 독립적이기 때문에 다른 컴포넌트의 값을 직접적으로 참조할 수 없음

더보기

앵귤러1이나 백본과 같은 초창기 자바스크립트 프레임워크에서는 한 화면을 1개의 뷰로 간주

따라서 한 화면의 데이터를 해당 화면 영역 어디에서든지 호출할 수 있었음

<html>
<head>
    <title>Vue Component Scope</title>
</head>
<body>
    <div id="app">
        <my-component1></my-component1>
        <my-component2></my-component2>
    </div>

    <!--script단-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <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>
</body>
</html>

 

<my-component2>의 cmp2Data는 100으로 값이 뜨지 않음

=> 컴포넌트의 유효 범위로 인해 다른 컴포넌트의 값을 직접 접근하지 못하기 때문에

 

이렇게 컴포넌트 값을 참조하지 못하기 때문에 생기는 특징

 - 뷰에서 미리 정의해 놓은 데이터 전달 방식에 따라 일관된 구조로 애플리케이션을 작성하게 됨

 - 개발자 개개인의 스타일대로 구성되지 않고, 애플리케이션이 모두 동일한 데이터 흐름을 가짐

 - 다른 사람의 코드를 빠르게 파악할 수 있어 협업하기에 좋음


상 · 하위 컴포넌트 관계

 

컴포넌트의 유효범위 때문에 다른 컴포넌트 값을 참조할 수 없음 => 뷰 프레임워크 자체에서 정의한 컴포넌트 데이터 전달 방법을 따라야 함

기본적인 데이터 전달 방법 :  상위(부모) - 하위(자식) 컴포넌트 데이터 전달 방법

 

상위-하위 컴포넌트 : 트리 구조에서 부모노드, 자식노드처럼 컴포넌트 관계가 부모,자식으로 이루어진 컴포넌트

상위 => 하위 : props 속성 전달

하위 => 상위 : 기본적 이벤트만 전달

 


상위에서 하위컴포넌트로 데이터 전달하기

props 속성

props는 상위컴포넌트에서 하위컴포넌트로 데이터를 전달할 때 사용하는 속성

props 속성을 사용하려면 하위 컴포넌트의 속성을 정의

그 다음 상위컴포넌트의 HTML 코드에 등록된 child-component 컴포넌트 태그에 v-bind 속성을 추가

Vue.component('child-component', {
	props: ['props속성이름'],
});
<child-component v-bind: props속성이름 = "상위컴포넌트data속성"></child-component>

 

상위 컴포넌트를 딱히 지정하지 않더라도, 뷰에서는 마치 상위 컴포넌트가 존재하는 것처럼 하위 컴포넌트로 props를 내려보냄

컴포넌트를 등록함과 동시에 뷰 인스턴스 자체가 상위 컴포넌트가 되기 때문

인스턴스에 새로운 컴포넌트를 등록하면 기존 컴포넌트는 상위 컴포넌트가 되고, 새로 등록된 컴포넌트는 하위컴포넌트가 됨

이렇게 새 컴포넌트를 등록한 인스턴스 : 최상위 컴포넌트(Root Component)


하위에서 상위컴포넌트로 이벤트 전달하기

이벤트 발생과 수신

하위 -> 상위 : 이벤트를 발생(event emit) -> 상위 컴포넌트에 신호 보내기

상위 컴포넌트에서 하위 컴포넌트의 특정 이벤트가 발생하기를 기다림

하위 컴포넌트에서 특정 이벤트가 발생하면 해당 이벤트를 수신해 상위 컴포넌트의 메서드를 호출

더보기

하위에서 상위 컴포넌트로 데이터를 전달할 수는 없나요?

뷰 공식 사이트의 이벤트 발생 사용 방법에서는 하위에서 상위로 데이터를 전달하는 방법X

뷰의 단방향 데이터 흐름에 어긋나는 구현 방법이기 때문

하지만 향후에 복잡한 뷰 애플리케이션을 구축할 때 이벤트 버스(Event Bus)를 이용해 데이터를 전달해야 할 경우가

있기 때문에 이벤트 인자로 데이터를 전달하는 방법이 있음

 

이벤트 발생과 수신 형식

// 이벤트 발생
this.$emit('이벤트명');

// 이벤트 수신
<child-component v-on:이벤트명="상위 컴포넌트의 메서드명"></child-component>

$emit() : 괄호 안에 정의된 이벤트가 발생함

일반적으로 $emit()을 호출하는 위치 : 하위 컴포넌트의 특정 메서드 내부

this : 하위 컴포넌트를 가리킴

 

호출한 이벤트는 하위 컴포넌트를 등록하는 태그에서 v-on으로 받음(상위 컴포넌트의 template 속성에 위치)


같은 레벨의 컴포넌트 간 통신

뷰는 상위에서 하위로만 데이터를 전달해야함

바로 옆 컴포넌트에 값을 전달하기 위해 : 공통 상위 컴포넌트로 이벤트를 전달한 후 2개의 하위 컴포넌트에 props 를 내려 보내야함

But 상위 컴포넌트가 필요없는 경우, 강제로 상위컴포넌트가 필요하기 때문에 불편 => 이벤트 버스를 사용함


관계 없는 컴포넌트 간 통신 - 이벤트 버스

 

 

이벤트 버스 : 개발자가 지정한 2개의 컴포넌트 간에 데이터를 주고받을 수 있는 방법

상위-하위 관계를 유지하지 않아도 데이터를 한 컴포넌트에서 다른 컴포넌트로 전달할 수 있음

 

//이벤트 버스를 위한 추가 인스턴스 1개 생성
var eventBux = new Vue();

//이벤트를 보내는 컴포넌트
methods: {
	메서드명: function(){
    	eventBus.$emit('이벤트명', '데이터');
    }
}

//이벤트를 받는 컴포넌트
methods: {
	created: function(){
    	eventBus.$on('이벤트명', function(){
        	...
        });
    }
}

 

 

이벤트 버스를 구현하기 위해, 새로운 인스턴스를 1개 더 생성

새 인스턴스를 이용해 이벤트를 보내고 받음

보내는 컴포넌트 => .$emit()

받는 컴포넌트 => .$on()

 

 

반응형
댓글