뷰 컴포넌트
컴포넌트는 조합하여 화면을 구성할 수 있는 블록을 의미합니다.
컴포넌트를 활용하면 화면을 빠르게 구조화하여 일괄적인 패턴으로 개발할 수 있습니다.
뷰에서 웹하면을 구성할 때 흔히 네비게이션 바, 테이블, 리스트, 인풋 박스 등 화면 구성 요소들을 컴포넌트로 관리합니다.
컴포넌트 등록
그럼 전역 컴포넌트와 지역 컴포넌트를 등록해보겠습니다.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Vue Sample</title>
</head>
<body>
<div id="app">
<kimn-global-component></kimn-global-component>
<kimn-local-component></kimn-local-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
Vue.component('kimn-global-component', {
template: '<div>Check Global Component</div>'
});
var cmp = {
template: '<div>Check Local Component</div>'
};
new Vue({
el: '#app',
components: {
'kimn-local-component': cmp
}
});
</script>
</body>
</html>
전역 컴포넌트는 Vue 생성자에 .component()를 호출하면 됩니다.
지역 컴포넌트는 인스턴스에 components 속성을 추가하고 등록할 컴포넌트 이름과 내용을 정의합니다.
지역과 전역 컴포넌트의 차이는 유효 범위입니다.
위에 이미지는 모두 출력시킨 화면이며 차이를 보이도록 소스를 작성해봅시다!
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Vue Sample</title>
</head>
<body>
<div id="app">
<h3>First Component</h3>
<kimn-global-component></kimn-global-component>
<kimn-local-component></kimn-local-component>
</div>
<div id="app2">
<h3>Second Component</h3>
<kimn-global-component></kimn-global-component>
<kimn-local-component></kimn-local-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
Vue.component('kimn-global-component', {
template: '<div>Check Global Component</div>'
});
var cmp = {
template: '<div>Check Local Component</div>'
};
new Vue({
el: '#app',
components: {
'kimn-local-component': cmp
}
});
new Vue({
el: '#app2'
});
</script>
</body>
</html>
app2 태그를 하나 더 추가해보겠습니다.
똑같이 전역, 지역 컴포넌트를 모두 등록하여 실행시켜보겠습니다.
app2에서는 지역 컴포넌트를 인식하지 못하는 것을 확인할 수 있습니다.
뷰 컴포넌트 통신
Angular 프레임워크 이용하시면 한 화면을 1개의 뷰로 간주해서 한 화면의 데이터를 해당 화면 영역 어디서든 호출이 가능합니다.
Vue는 컴포넌트이기에 같은 웹 페이지여도 유효 범위를 갖고 있기 때문에 공유할 수 없습니다.
Vue 프레임워큰는 내부적으로 정의하여 유효 범위가 독립적이기 때문에 직접적으로 참조할 수 없습니다.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Vue Sample</title>
</head>
<body>
<div id="app">
<h3>First Component</h3>
<kimn-local-component></kimn-local-component>
<kimn-local-component-2></kimn-local-component-2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
var cmp = {
template: '<div>Check Local Component : {{ cmpdata_1 }}</div>',
data: function() {
return {
cmpdata_1 : 100
}
}
};
var cmp2 = {
template: '<div>Check Local Component : {{ cmpdata_2 }}</div>',
data: function() {
return {
cmpdata_2 : cmp.data.cmp-data
}
}
};
new Vue({
el: '#app',
components: {
'kimn-local-component': cmp,
'kimn-local-component-2': cmp2
}
});
</script>
</body>
</html>
component-2는 component를 직접 참조할 수 없기 때문에 출력되지 않습니다.
※ return 내부의 단어에 ' - ' 글자는 토큰으로 받을 수 없어 ' _ ' 로 입력하였습니다.
위와같이 다른 컴포넌틍의 값을 참조할 수 없습니다.
따라서 Vue 프레임워크 자체에서 정의한 데이터 전달 방법을 이용하셔야 합니다.
그 중 가장 기본적인 방법은 상위-하위 컴포넌트 전달이 있습니다.
상위 - 하위 컴포넌트
상위에서 하위로 데이터를 전달할 때 props 속성을 이용합니다.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Vue Sample</title>
</head>
<body>
<div id="app">
<child-component v-bind:propsdata = "message"></child-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
Vue.component('child-component', {
props: ['propsdata'],
template: '<p>{{ propsdata }}</p>',
});
new Vue({
el: '#app',
data: {
message: 'Parent Component Data'
}
});
</script>
</body>
</html>
new Vue() 인스턴스 먼저 생성 후, Vue.component()를 이용하여 하위 컴포넌트를 등록합니다.
그 후 v-bind 속성을 이용하여 상위 컴포넌트 message 속성 값을 하위 컴포넌트로 전달하여 출력합니다.
하위에서 상위로 전달할 때 이벤트를 발생시켜 신호를 보냅니다.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Vue Sample</title>
</head>
<body>
<div id="app">
<child-component v-on:check-log = "printcheck"></child-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
Vue.component('child-component', {
template: '<button v-on:click="checkLog">check</button>',
methods: {
checkLog: function() {
this.$emit('check-log');
}
}
});
new Vue({
el: '#app',
data: {
message: 'Parent Component Data'
},
methods: {
printcheck: function() {
console.log("received an event");
}
}
});
</script>
</body>
</html>
v-on 속성을 이용해 하위 컴포넌트에서 발생한 이벤트를 지정하여 호출될 상위 컴포넌트의 메서드를 지정합니다.
해당 방식으로 하위에서 상위로 신호를 올려 상위 컴포넌트의 메서드를 실행할 수 있고, props 값도 조정할 수 있습니다.
그럼 같은 레벨에 있는 컴포넌트들은 어떻게 통신을 할 수 있을까?
이벤트 버스
해당 방식은 지정한 2개의 컴포넌트 간에 데이터를 주고받을 수 있는 방식입니다.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Vue Sample</title>
</head>
<body>
<div id="app">
<child-component></child-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
var eventBus = new Vue();
Vue.component('child-component', {
template: '<button v-on:click="checkLog">check</button>',
methods: {
checkLog: function() {
eventBus.$emit('check-log', 100);
}
}
});
new Vue({
el: '#app',
created: function() {
eventBus.$on('check-log', function(value) {
console.log("received an event value : ", value);
});
}
});
</script>
</body>
</html>
이와같이 두개의 컴포넌트를 지정하여 데이터를 주고 받을 수 있습니다.
'Develop > Vue' 카테고리의 다른 글
Vue 템플릿 (0) | 2020.01.26 |
---|---|
Vue HTTP 통신 (0) | 2020.01.26 |
Vue Router (0) | 2020.01.26 |
Vue 세팅하기 (0) | 2020.01.26 |
[Nuxt.js] 설명 및 Nginx / PM2 연동 (0) | 2020.01.26 |