Vue.js - 컴포넌트
정의된 컴포넌트는 사용자 정의 엘리먼트 형식으로 사용
전역 등록
Vue.component('todo-item', {
template: '<li>할일 항목 하나입니다.</li>'
})
<ol>
<todo-item></todo-item>
</ol>
지역 등록
components 옵션 설정
new Vue({
el: '#app',
components: {
'todo-item': {
template: '<li>할일 항목 하나입니다.</li>'
}
}
});
컴포넌트 데이터
props에 template에서 사용할 변수명 정의(todo)
props를 통해 데이터의 출처를 명확히 하면 다른 상황에서 컴포넌트를 재사용할 수 있습니다.
각 구성 요소에는 “키”를 제공해야함.
- 전역 등록
Vue.component('todo-item', {
props: ['todo'],
template: '<li></li>'
});
var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Whatever else humans are supposed to eat' }
]
}
})
- 지역 등록
new Vue({
el: '#app',
data: {
groceryList: [
{ id: 1, text: 'item 1'},
{ id: 2, text: 'item 2'},
{ id: 3, text: 'item 3'},
]
},
components: {
'todo-item': {
props: ['todo'],
template: '<li></li>'
}
}
});
<div id="app-7">
<ol>
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id">
</todo-item>
</ol>
</div>
일부 엘리먼트 제한
- DOM을 템플릿으로 사용할 때 <ul>, <ol>, <table>,
- 문자열 템플릿(가능한 경우 항상 문자열 템플릿을 사용하는 것이 좋습니다.)
- JavaScript 인라인 템플릿 문자열
- .vue 컴포넌트
- ‘is’ 특수 속성
- 문자열 템플릿(가능한 경우 항상 문자열 템플릿을 사용하는 것이 좋습니다.)
<table>
<tr is="my-row"></tr>
</table>
컴포넌트내 data는 함수여야합니다.
new Vue({
el: '#app',
components: {
'my-component':{
template: '<span></span>',
data: function() {
return {
message: 'hello'
};
}
}
}
});
컴포넌트 props camelCase는 html 속서명 kebab-case로 매칭 된다.
Vue.component('child', {
// JavaScript는 camelCase
props: ['myMessage'],
template: '<span></span>'
})
<!-- HTML는 kebab-case -->
<child my-message="안녕하세요!"></child>
부모-자식 컴포넌트 관계
Vue.js에서 부모-자식 컴포넌트 관계는 props는 아래로, events 위로 라고 요약 할 수 있습니다.
부모는 props를 통해 자식에게 데이터를 전달하고 자식은 events를 통해 부모에게 메시지를 보냅니다
v-on을 이용한 사용자 지정 이벤트($emit)
자식 컨포넌트가 부모에게 이벤트를 전송하는 방법
태그에 선언된 increment를 기준으로 부모 method를 바인딩하고 자식에서는 $emit(‘increment’)를 통해 호출.
<div id="counter-event-example">
<p></p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
Vue.component('button-counter', {
template: '<button v-on:click="incrementCounter"></button>',
data: function () {
return {
counter: 0
}
},
methods: {
incrementCounter: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})