Vue 컴포넌트
- 화면을 조합해서 구성할 수 있게 블럭형태로 분할 된 화면영역(Component)을 의미
- 컴포넌트 간의 관계는 일반적으로 Tree 구조
- 화면 구성요소의 재활용
- 각 컴포넌트는 각각의 고유한 유효범위를 가짐
전역(Global) 컴포넌트
- Vue 변수를 사용해서 등록하는 컴포넌트
- 모든 인스턴스에서 접근 가능
- 일반적으로 전역 컴포넌트를 선언해서 사용하는 경우는 거의 없음, 대부분 플러그인, 3thParty 라이브러리 사용 시 활용 됨
Vue.component("global-component", {
template: "<h1>Content</h1>",
});
지역(Local) 컴폰너트
- Vue 인스턴스에서 'components' 속성을 사용해서 정의
- 해당 인스턴스의 유효범위 내에서만 사용 가능
new Vue({
el: "#app",
components: {
// '#app' html엘리먼트 내에서만 사용 가능
"local-component": {
template: "<div>Content</div>",
},
},
});
컴포넌트 간 통신
- Vue인스턴스 고유한 유효범위로 다른 인스턴스의 값을 직접 접근 불가
- Vue의 기본 데이터 통신 방식
- '상위 컴포넌트 -> 하위 컴포넌트' [데이터] 전달
- '하위 컴포넌트 -> 상위 컴포넌트' [이벤트] 전달
=> 데이터의 흐름을 쉽게 추적 가능하고 관리가 용이
[Props] 상위 컴포넌트 -> 하위 컴포넌트
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<app-header v-bind:propsdata="message"></app-header>
</div>
<script>
var appHeader = {
template: "<h1>{{propsdata}}</h1>",
props: ["propsdata"],
};
new Vue({
el: "#app",
components: {
"app-header": appHeader,
},
data: {
message: "hi",
},
});
</script>
</body>
상위컴포넌트의 'message' 데이터를 하위컴포넌트로 전달하여 화면에 출력.
<app-header v-bind:propsdata="message"></app-header> 에서 상위컴포넌트의 message를 하위컴포넌트의 propsdata로 전달.
[emit] 하위 컴포넌트 -> 상위 컴포넌트 샘플
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{ num }}
<!--
이벤트 수신
<app-header v-on:하위컴포넌트에서 발생하는 이벤트:상위컴포넌트의 메소드명></app-header>
-->
<app-content v-on:pass-add="addNum"></app-content>
</div>
<script>
var appContent = {
template: "<button v-on:click='addNumber'>add</button>",
methods: {
addNumber: function () {
this.$emit("pass-add"); // 이벤트 발생
},
},
};
new Vue({
el: "#app",
components: {
"app-content": appContent,
},
methods: {
addNum: function () {
console.log(this.num);
this.num++;
},
},
data: {
num: 10,
},
});
</script>
</body>
하위컴포넌트에서 버튼 클릭 시 $emit으로 "pass-add"라는 이름의 이벤트를 발생 시키면
=> <app-content v-on:pass-add="addNum"></app-content>에서 pass-add이벤트에 대해 상위컴포넌트의 addNum 메소드 호출 후 숫자 +1 처리
같은 레벨 컴포넌트 간 통신
컴포넌트 A -> 컴포넌트 B로 데이터 전달 할 경우
A컴포넌트 -> (emit) -> 상위컴포넌트 -> (props) -> B 하위컴포넌트
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<app-header v-bind:propsdata="num"></app-header>
<app-content v-on:pass="deliverNum"></app-content>
</div>
<script>
var appHeader = {
template: "<div> {{ propsdata }}</div>",
props: ["propsdata"],
};
var appContent = {
template: `<div>
<button v-on:click="passNum">버튼</button>
</div>`,
methods: {
passNum() {
this.$emit("pass", 10);
},
},
};
new Vue({
el: "#app",
components: {
"app-header": appHeader,
"app-content": appContent,
},
data: {
num: 0,
},
methods: {
deliverNum(value) {
this.num = value;
},
},
});
</script>
</body>
appContent 컴포넌트에서 버튼 클릭 시 $emit("pass", 10) 이벤트와 값을 넘김
=> <app-content v-on:pass="deliverNum"></app-content> 에서 pass이벤트 받아서 상위컴포넌트의 deliverNum메소드 호출
=> deliverNum()에서 상위컴포넌트 data의 num 변경
=> <app-header v-bind:propsdata="num"></app-header> 에서 num값이 appHeader컴포넌트의 propsdata로 바인딩 됨
=> appHeader컴포넌트의 propsdata 화면 출력
EventBus 사용
- 상하위 기본 데이터 전송 규칙과 관계없이 지정한 컴포넌트 간에 데이터를 주고 받을 수 있는 방법
- EventBus용 별도 Vue 인스턴스 사용해서 이벤트 발생($emit) 및 수신 처리($on)
- 컴포넌트 간 직접 통신으로 편리하지만 많아질 경우 데이터 관리 어려움 => 상태관리도구 필요(Vuex)
<body>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<app-header></app-header>
<app-content></app-content>
</div>
<script>
// EventBus 용 별도 Vue 인스턴스 생성
var eventBus = new Vue();
var appHeader = {
template: "<div>header</div>",
// created에서 EventBus 이벤트 리스너 설정
created() {
eventBus.$on("pass", function (value) {
console.log(value);
});
},
};
var appContent = {
template: `<div>
<button v-on:click="passNum">버튼</button>
</div>`,
methods: {
passNum() {
eventBus.$emit("pass", 10); // EventBus로 이벤트 발생
},
},
};
new Vue({
el: "#app",
components: {
"app-header": appHeader,
"app-content": appContent,
},
});
</script>
</body>
appContent 컴포넌트와 appHeader컴포넌트 직접 통신
var eventBus = new Vue(); 로 이벤트 버스용 인스턴스 생성
=> appContent컴포넌트에서 버튼 클릭 시 eventBus.$emit("pass", 10) 이벤트와 값을 넘김
=> appHeader컴포넌트 created 라이프사이클 훅에서 eventBus.$on()으로 "pass"이벤트 수신 처리
'개발 > Vue.js' 카테고리의 다른 글
Vue.js Font Awesome 아이콘 사용 (0) | 2022.03.22 |
---|---|
Vue-CLI 시작하기(프로젝트 생성 및 디렉토리 구조) (0) | 2022.03.21 |
Vue.js Router 개념 및 구성 (0) | 2022.03.19 |
Vue.js 인스턴스 - 옵션(속성) 및 라이프사이클 (0) | 2022.03.16 |
Vue.js란 무엇인가? - Hello World (0) | 2022.03.16 |
댓글