1. 컴포넌트2. 컴포넌트 등록2.1 전역 컴포넌트 등록2.2 지역 컴포넌트 등록2.3 지역컴포넌트와 전역컴포넌트 동작 비교3. 컴포넌트 통신3.1 부모 → 자식 컴포넌트로 데이터 전달 (props)3.2 자식 → 부모 컴포넌트로 데이터 전달 (v-on, $emit)3.3 부모 ↔ 자식의 관계가 아닌 컴포넌트 통신 (이벤트버스)
1. 컴포넌트
- 컴포넌트는 Vue의 가장 강력한 기능 중 하나
- 기본 HTML 엘리먼트를 확장하여 재사용 가능한 코드를 캡슐화 하는데 도움
- 뷰컴포넌트는 뷰인스턴스이기도 하기 때문에, 모든 옵션 객체와 라이프사이클 훅 사용 가능
2. 컴포넌트 등록
컴포넌트를 등록하는 방법은 두 가지가 있음
전역 등록: 특정 인스턴스에서만 사용 가능
지역 등록: 뷰로 접근 가능한 모든 범위 사용 가능
2.1 전역 컴포넌트 등록
xxxxxxxxxx
<div id="example">
<grobal-component></grobal-component>
</div>
xxxxxxxxxx
// 전역 컴포넌트 등록
Vue.component('grobal-component', {
template: '<div>전역 컴포넌트 입니다!</div>'
})
// 루트 인스턴스 생성
new Vue({
el: '#example'
})
2.2 지역 컴포넌트 등록
xxxxxxxxxx
<div id="example">
<local-component></local-component>
</div>
xxxxxxxxxx
// 컴포넌트 정의
var Child = {
template: '<div>지역 컴포넌트 입니다!</div>'
}
new Vue({
el: '#example',
//지역 컴포넌트 등록
components: {
'local-component': Child
}
})
2.3 지역컴포넌트와 전역컴포넌트 동작 비교
2개의 뷰인스턴스 생성(app1, app2)
xxxxxxxxxx
<div id="app1">
<h3>app1 인스턴스 영역</h3>
<local-component></local-component>
<global-component></global-component>
</div>
<hr>
<div id="app2">
<h3>app2 인스턴스 영역</h3>
<local-component></local-component>
<global-component></global-component>
</div>
xxxxxxxxxx
// 전역 컴포넌트 생성
Vue.component('global-component', {
template: '<div>전역 컴포넌트</div>'
})
// 지역 컴포넌트 정의
var cmp = {
template: '<div>지역 컴포넌트 등록</div>'
}
//app1 인스턴스 생성, 지역컴포넌트 등록
new Vue({
el: '#app1',
components:{
'local-component': cmp
}
})
//app2 인스턴스 생성
new Vue({
el: '#app2',
})
실행 결과
- 전역컴포넌트는 app1, app2 뷰인스턴스에 모두 적용
- 지역컴포넌트는 app1 인스턴스에만 적용
3. 컴포넌트 통신
컴포넌트는 자체적으로 고유한 유효 범위(Scope)를 갖고 있음
- 유효 범위가 독립적이기 때문에, 서로 다른 컴포넌트의 값을 직접적으로 참조할 수 없음
컴포넌트끼리의 통신을 위해 Vue.js에서 별도의 옵션을 제공
부모-자식 컴포넌트 관계에서, 방향에 따라 옵션이 다름
- 부모 → 자식: props
- 자식 → 부모: events
3.1 부모 → 자식 컴포넌트로 데이터 전달 (props)
- props 정의
xxxxxxxxxx
Vue.component('child', {
props: ['message'],
template: '<span>{{ message }}</span>'
})
- props 예제
xxxxxxxxxx
<div id="app">
<!-- v-bind 옵션을 이용하여 부모의 데이터를 바인딩 함 -->
<child-component v-bind:propsdata="message"></child-component>
<!-- v-bind 단축 구문 사용-->
<child-component :propsdata="props"></child-component>
</div>
xxxxxxxxxx
// 자식 컴포넌트 생성 (전역 컴포넌트)
// 이 컴포넌트는 app 컴포넌트 하위에 위치하므로 자식 컴포넌트가 됨
Vue.component('child-component', {
props: ['propsdata'], //props 명칭 선언
template: '<p>{{propsdata}}</p>' //컴포넌트에 표시할 내용
})
// 뷰 인스턴스 생성(부모 컴포넌트)
new Vue({
el: '#app',
data: {
message: '부모가 자식에게 보내는 메시지',
props: '부모가 자식에게 메시지를 보낼 때 props를 사용'
}
})
3.2 자식 → 부모 컴포넌트로 데이터 전달 (v-on, $emit)
v-on:이벤트명="메소드명"
- 이벤트 감지 역할, 해당 이벤트가 발생하면 정의된 메소드를 호출
$emit(이벤트명,데이터)
- 이벤트 발생 역할, $emit을 호출하는 시점에 이벤트를 발생 시킴
- 데이터 파라미터 생략 가능 → $emit(이벤트명)
xxxxxxxxxx
<div id="event-example">
<p>{{ message }}</p>
<!-- send-event 이벤트가 발생하면 getEvent 메소드 호출 -->
<button-counter v-on:send-event="getEvent"></button-counter>
</div>
xxxxxxxxxx
//자식 컴포넌트 생성 및 이벤트 정의
Vue.component('button-counter', {
//버튼 클릭 시, sendEvent 메소드 호출
template: '<button v-on:click="sendEvent">버튼</button>',
methods: {
sendEvent: function () {
//send-evnet 이벤트 발생
this.$emit('send-event', "Hi")
}
},
})
//부모 컴포넌트 생성
new Vue({
el: '#event-example',
data: {
message: "이벤트 받기 전"
},
methods: {
//이벤트가 발생 시, 호출 할 메소드 생성
getEvent: function (msg) {
this.message = "이벤트를 받았습니다. " + msg
}
}
})
3.3 부모 ↔ 자식의 관계가 아닌 컴포넌트 통신 (이벤트버스)
- 이벤트 버스를 위한 뷰 인스턴스 생성
- $emit 메소드를 이용하여 이벤트 전달
- $on 메소드를 이용하여 이벤트 수신
xxxxxxxxxx
<div id="app1">
<h3>첫번째 컴포넌트 영역</h3>
<first-component></first-component>
</div>
<div id="app2">
<h3>두번째 컴포넌트 영역</h3>
<second-component></second-component>
</div>
xxxxxxxxxx
//이벤트 버스 인스턴스
var eventBus = new Vue();
// app1의 자식 컴포넌트
// 버튼을 누르면 $emit을 통해 triggerEventBus 이벤트를 발생시킴
Vue.component('first-component', {
template: '<div>자식 컴포넌트<button v-on:click="sendEvent">버튼</button></div>',
methods: {
sendEvent: function () {
eventBus.$emit('triggerEventBus', 100)
}
},
})
// app2의 자식 컴포넌트
// $on을 통해 triggerEventBus가 발생하면 로그를 출력
Vue.component('second-component', {
template: '<p>자식 컴포넌트</p>',
created: function(){
eventBus.$on('triggerEventBus', function(msg){
console.log("이벤트 전달받음. 전달받은 값: " + msg);
});
}
})
//부모 인스턴스 생성
new Vue({
el: '#app1'
})
new Vue({
el: '#app2'
})
props 속성을 이용하지 않고, 원하는 컴포넌트간에 직접적으로 데이터를 전달하여 편리함
- 컴포넌트가 많아지면 관리가 되지 않는 문제 발생
- 이 문제를 해결하기위해 뷰엑스(Vuex)라는 상태 관리 도구 필요
반응형
'Web > Vue.js' 카테고리의 다른 글
[Vue.js] - HTML5 WebSocket(웹 소켓) 소스코드 및 데모 사이트 (0) | 2020.11.13 |
---|---|
Vue.js 뷰 템플릿 정리 (5) (0) | 2020.05.07 |
Vue.js 뷰 라우터 정리 (4) (0) | 2020.04.29 |
Vue.js 뷰인스턴스 (2) (0) | 2020.04.21 |
Vue.js란 무엇인가? (1) (1) | 2020.04.20 |
댓글