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

Vue 뷰는 컴포넌트로 화면을 구성하므로 같은 웹 페이지라도 데이터를 공유할 수 없다. 그 이유는 컴포넌트마다 자체적으로 고유한 유효 범위(scope)를 갖기 때문이다. 따라서, 각 컴포넌트의 유효 범위가 독립적이기 때문에 다른 컴포넌트의 값을 직접적으로 참조할 수 없다.

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>컴포넌트 유효 범위 증명</title>
</head>
<body>
    <div id="app">
        <my-component1></my-component1>
        <my-component2></my-component2>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/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.cmp10Data
                }
            }
        }; 

        new Vue({
            el:'#app',
            components:{
                'my-component1':cmp1,
                'my-component2':cmp2
            }
        });
    </script>
</body>
</html>

이 예제는 2개의 지역 컴포넌트를 등록하고 첫 번째 지역 컴포넌트는 직접 값을 입력하여 출력하지만 두 번째 컴포넌트는 첫 번째 값을 참조하여 출력하는 코드이다. 실행하면 첫 번째 값은 나오지만 두 번째 값은 나오지 않는 것을 확인할 수 있다. 왜 두 번째 컴포넌트의 값은 나타나지 않을까? 컴포넌트의 유효 범위로 인해 다른 컴포넌트의 값을 직접 접근하지 못하기 때문이다. 

 

상위-하위 컴포넌트 데이터 전달방법

이렇게 직접 다른 컴포넌트의 값을 참조할 수 없지만 뷰 프레임워크에서 정의한 컴포넌트 데이터 전달 방법인 상위(부모)-하위(자식) 컴포넌트를 따라야 한다.

 

상위에서 하위 컴포넌트로 데이터 전달하는 방법

 

상위에서 하위 컴포넌트로 데이터를 전달하기 위해서는 props 속성을 사용해야 한다.

Vue.component('child-component',{props:['props 속성 이름'],});
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>props 속성을 사용한 데이터 전달</title>
</head>
<body>
    <div id="app">
        <child-component v-bind:propsdata="message"></child-component>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <script>
        Vue.component('child-component',{
            props:['propsdata'],
            template:'<p>{{propsdata}}</p>'
        });

        new Vue({
            el:'#app',
            data:{
                message: 'Hello Vue! passed from parent Component'
            }
        })
    </script>
</body>
</html>

이 예제는 상위 컴포넌트의 message 속성을 하위 컴포넌트에 props로 전달하여 메세지를 출력하는 예제이다. 출력은 Hello Vue! passed from parent Component가 나올것이다. 

 

하위에서 상위 컴포넌트로 이벤트 전달하는 방법

this.$emit('이벤트 명'); //이벤트 발생
<child-component v-on:이벤트명="상위 컴포넌트의 메서드명"></child-component> //이벤트 수신

이벤트 발생과 수신은 $emit와 v-on 속성을 사용하여 구현한다. $emit()을 호출하면 괄호 안에 있는 정의된 이벤트가 발생한다. 여기에 this는 하위 컴포넌트를 의미한다. v-on 속성은 속성의 값에 이벤트가 발생했을 때 호출될 상위 컴포넌트의 메서드를 지정한다.

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>이벤트를 발생시키고 수신하기</title>
</head>
<body>
    <div id="app">
        <child-component v-on:show-log="printText"></child-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component('child-component',{
            template:'<button v-on:click="showLog">show</button>',
            methods:{
                showLog:function(){
                    this.$emit('show-log');
                }
            }
        });

        var app= new Vue({
            el:'#app',
            data:{
                message:"Hello vue! passed from parent component"
            },
            methods:{
                printText:function(){
                    console.log("received an event");
                }
            }
        });
    </script>
</body>
</html>

이 예제는 child-component의 show버튼을 클릭하여 이벤트를 발생시키고, 발생한 이벤트로 상위 컴포넌트의 printText() 메서드를 실행시키는 코드이다.

이 글을 공유하기

댓글

Designed by JB FACTORY