![article thumbnail image](https://blog.kakaocdn.net/dn/mmzmz/btrFZZF0I8n/3bKdf551aNDNBfKBKUAKZK/img.png)
전역 컴포넌트 등록
Vue.component('컴포넌트 이름', {
//컴포넌트 내용
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button>컴포넌트 등록</button>
<my-component></my-component>
</div>
<script>
Vue.component('my-component', {
template: '<div>전역 컴포넌트가 등록되었습니다!</div>'
});
new Vue({
el: '#app'
})
</script>
</body>
</html>
지역 컴포넌트 등록
new Vue({
components: {
'컴포넌트 이름' : 컴포넌트
}
});
<body>
<div id="app">
<button>컴포넌트 등록</button>
<my-component></my-component>
</div>
<div id="app1">
<button>컴포넌트 등록</button>
<my-local-component></my-local-component>
</div>
<script>
Vue.component('my-component', {
template: '<div>전역 컴포넌트가 등록되었습니다!</div>'
});
new Vue({
el: '#app',
})
var cmp = {
//컴포넌트 내용
template: '<div>지역 컴포넌트가 등록되었습니다!</div>'
};
new Vue({
el: '#app1',
components: {
'my-local-component': cmp
}
})
</script>
순서도 중요함! Vue 생성자 만들때 cmp보다 위에가있으면 출력결과가 나오지않는다.
뷰 컴포넌트 통신과 유효범위
앵귤러, 백본과 다르게 뷰는 컴포넌트로 화면을 구성하므로 데이터 공유가 불가
- 컴포넌트 마다 자체적으로 고유한 스코프를 갖고있기때문에 다른 컴포넌트의 값을 직접참조 할 수 없다
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button>컴포넌트 등록</button>
<my-component></my-component>
</div>
<hr>
<div id="app1">
<button>컴포넌트 등록</button>
<my-local-component></my-local-component>
</div>
<hr>
<div id="app2">
<button>컴포넌트 등록</button>
<my-component1></my-component1>
<my-component2></my-component2>
</div>
<script>
Vue.component('my-component', {
template: '<div>전역 컴포넌트가 등록되었습니다!</div>'
});
new Vue({
el: '#app',
})
var cmp = {
//컴포넌트 내용
template: '<div>지역 컴포넌트가 등록되었습니다!</div>'
};
new Vue({
el: '#app1',
components: {
'my-local-component': cmp
}
})
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: '#app2',
components: {
'my-component1': cmp1,
'my-component2': cmp2
}
})
</script>
</body>
</html>
2개의 지역 컴포넌트를 등록하고 한 컴포넌트에서 첫번째 지역 컴포넌트 값을 직접 참조했을 때
컴포넌트 유효범위(스코프)로인해 아무것도 표시되지 않는다.
상하위컴포넌트관계
컴포넌트간 스코프로인해 뷰 프레임워크에서는 상위-하위 컴포넌트간의 데이터 전달을 이용해야한다.
상위-하위 컴포넌트?
트리구조에서 부모노드, 자식노드처럼 컴포넌트 관계가 부모-자식 으로 이루어진 컴포넌트
상위에서 하위로는 props라는 속성을 전달한다.
하위에서 상위로는 기본적으로 이벤트만 전달 가능
상위에서 하위 컴포넌트로 데이터 전달하기
props?
Vue.component('child-component', {
props: ['props 속성이름']
});
하위 컴포넌트의 속성에 정의 한 후
<child-component v-bind:props 속성 이름="상위 컴포넌트의 data속성"></child-component>
상위 컴포넌트의 HTML 코드에 등록된 child-component 태그에 v-bind 속성을 추가한다
v-bind 속성의 왼쪽값으로 하위 컴포넌트에서 정의한 props 속성을 넣고, 오른쪽 값으로 하위컴포넌트에 전달할 상위 컴포넌트의 data속성지정
예제
<body>
<div id="app">
<child-component v-bind:propsdata="message"></child-component>
</div>
<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>
예제에서 child-component를 전역으로 등록한 것 외에 상위 컴포넌트를 지정하지 않았어도 상위컴포넌트가 존재하는 것처럼 props를 받았다. 이유는 컴포넌트를 등록함과 동시에 뷰 인스턴스 자체가 상위 컴포넌트가 됐기 때문.
==> 자바 super생각하면 될듯
props는 상위에서 하위 컴포넌트로 전달하는것이었다면
이번엔 하위에서 상위 컴포넌트로 이벤트 전달하기
- 이벤트를 발생시켜(event emit) 상위 컴포넌트에 신호를 보낸다.
- 하위 컴포넌트에서 특정 이벤트가 발생하면 상위 컴포넌트에서 해당 이벤트를 수신하여 상위 메서드를 호출
이벤트 발신과 수신형식
//이벤트 발생 $emit()
this.$emit('이벤트명');
//이벤트 수신 v-on
<child-component v-on:이벤트명="상위컴포넌트의 메서드명"></child-component>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child-component v-on:show-log="printText"></child-component>
</div>
<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>
![](https://blog.kakaocdn.net/dn/bAyUQO/btrFYwSuI7I/T2O3ABbwmervhaQzfWfNZK/img.png)
![](https://blog.kakaocdn.net/dn/bo7Lvr/btrFViOraRe/h833Klnnr84mP2YALNY1c1/img.png)
child-component [show]버튼을 클릭하여 이벤트를 발생시키고 발생한 이벤트로 상위컴포넌트 printText() 메서드를 실행
같은레벨컴포넌트간 전달?
공통 상위 컴포넌트로 이벤트 전달 후 props
==> 상위 컴포넌트가 필요 없음에도 불구하고 같은 레벨간 통신을 위해 강제로 상위컴포넌트를 두어야하는 불편함
이를 해결하기위해 이벤트 버스 사용
이벤트버스?
개발자가 지정한 2개의 컴포넌트간 데이터를 주고받을 수 있는 방법
//이벤트 버스를 위한 추가 인스턴스 1개 생성
var eventBus = new Vue();
//이벤트를 보내는 컴포넌트 $emit
methods: {
메서드명: function(){
eventBus.$emit('이벤트명', 데이터);
}
}
//이벤트를 받는 컴포넌트 $on
methods: {
created: function(){
eventBus.$on('이벤트명', function(데이터){
...
});
}
}
애플리케이션 로직을 담는 인스턴스와는 별개로 새 인스턴스를 1개 더 생성 후 새 인스턴스를 이용하여 이벤트 송수신
<body>
<div id="app">
<child-component></child-component>
</div>
<script>
var eventBus = new Vue();
Vue.component('child-component', {
template: '<div>하위 컴포넌트 영역입니다. <button v-on:click="showLog">show</button></div>',
methods: {
showLog: function(){
eventBus.$emit('triggerEventBus', 100);
}
}
})
new Vue({
el: '#app',
created: function(){
eventBus.$on('triggerEventBus', function(value){
console.log("이벤트를 전달받음. 전달받은 값 : ", value);
});
}
})
</script>
</body>
![](https://blog.kakaocdn.net/dn/b13bVV/btrFT2kIigs/Bc9Ic2feFq7Z4lZ2UxrmI1/img.png)
![](https://blog.kakaocdn.net/dn/T4ONC/btrFYwZh4uQ/PPUYCtW0LfqKuxLjrUAfpK/img.png)
'개발 > Javascript' 카테고리의 다른 글
[Alpine] alpine.js 맛보기 (with 노마드코더) (0) | 2022.07.31 |
---|---|
[React] 페이지 라우팅 - React SPA & SCR (0) | 2022.07.28 |
[React] Page Routing; 페이지라우팅 | MPA와 SPA방식 차이 (0) | 2022.07.26 |
[React] 컴포넌트 트리에 데이터 공급. useContext와 Provider (0) | 2022.07.25 |
[Javascript] JSON 객체 (0) | 2022.07.25 |