뷰 컴포넌트 통신과 유효 범위
- 라이브러리/Vue.js
- 2019. 4. 10. 21:12
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() 메서드를 실행시키는 코드이다.
이 글을 공유하기