[Vue.js] 02 Component
2021. 9. 23. 14:07ㆍStudy/Vue.js
반응형
컴포넌트
- Vue.js가 제공하는 가장 강력한 기능 중 하나
- 컴포넌트는 HTML 마크업, 자바스크립트 로직을 포함한 하나의 덩어리
- 캡슐화가 자연스럽게 가능해지고 따라서 재사용이 가능해짐
전역 컴포넌트 선언
- Vue.component는 컴포넌트를 글로벌하게 등록하는 메서드
- 주의 : 확장된 Vue인스턴스, 즉 컴포넌트에서 data를 정의할때 반드시 함수로 정의해야함
- Tip: 컴포넌트 이름을 하이픈을 포함한 소문자여야 함
Vue.component('컴포넌트 이름', 컴포넌트 내용);
Vue.component('app-header', {
template: '<h1>Header</h1>'
});
Vue.component('app-content', {
template: '<div>content</div>'
});
지역 컴포넌트 선언
- 컴포넌트를 Vue인스턴스 혹은 컴포넌트의 옵션으로 등록해 해당 컴포넌트 내부에서만 사용하도록 지정
new Vue({
el: '#app',
components: { // key : value 형식
'app-footer': {
template: '<footer>footer</footer>'
}
}
});
혹은
var appFooter = {
template: '<footer>footer</footer>'
};
new Vue({
el: '#app',
components: { // key : value 형식
'app-footer': appFooter
}
});
제한사항
- ul, ol, table, select와 같은 일부 엘리먼트 내부에서는 컴포넌트를 사용할 수 없습니다.
- 제한 있는 엘리먼트 내부에 컴포넌트를 사용할 경우 문제 발생 > is 옵션을 사용해 정상적으로 렌더링 할 수 있음
컴포넌트 통신방식
- 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달하는 것이 가능
- 자식 컴포넌트는 부모 컴포넌트에게 데이터를 전달하는 것은 불가능
- 자식 컴포넌트가 부모 컴포넌트에게 이벤트를 전달해 부모 컴포넌트에게 메시지를 전달 가능
뷰 컴포넌트는 각각 고유한 데이터 유효 범위를 갖는다. 따라서, 컴포넌트 간에 데이터를 주고 받기 위해선 아래와 같은 규칙을 따라야한다.
- 상위에서 하위로는 데이터를 내려줌, props 전달
- 하위에서 상위로는 이벤트를 올려줌, event 발생
- 부모는 props를 통해 자식에게 데이터를 전달하고 자식은 events를 통해 부모에게 메시지를 보
Props
데이터 전달
- 모든 컴포넌트 인스턴스에는 자체 격리 된 범위 가 있다.
- 하위 컴포넌트의 템플릿에서 상위 데이터를 직접 참조할 수 없다.
- 데이터는 props 옵션을 사용하여 하위 컴포넌트로 전달하여야 한다.
- 하위 컴포넌트는 props 옵션을 사용하여 수신 할 것으로 기대되는 props를 명시적으로 선언해야한다.
Vue.component('child', {
// props 정의
props: ['myMessage'],
// 데이터와 마찬가지로 prop은 템플릿 내부에서 사용할 수 있으며
// vm의 this.message로 사용할 수 있습니다.
template: '<span>{{ message }}</span>'
})
- HTML 속성은 대소 문자를 구분하지 않으므로 문자열이 아닌 템플릿을 사용할 때 camelCased prop 이름에 해당하는 kebab-case(하이픈 구분)를 사용해야 한다.
<child v-bind:my-message="안녕하세요!"></child>
동적 props
- 정적 props : String 타입 외에 Number, Object, List 데이터는 전달할 수 없음. 또한 전달된 데이터는변경할 수 없음
- 동적으로 데이터를 전달하고 싶다면 v-bind를 이용해 데이터를 전달
- 부모 컴포넌트의 message가 변경된 경우 자식 컴포넌트는 다시 message 데이터를 받아 다시 렌더링
Event emit
- 자식 컴포넌트는 부모 컴포넌트에게 데이터를 전달할 수는 없지만 이벤트를 통해 메시지를 전달할 수 있음
- 자식 컴포넌트는 $emit을 이용해 이벤트를 실행
- Vue 인터페이스는 다음과 같은 이벤트 인터페이스를 구현
- $on(eventName)을 사용하여 이벤트를 감지
- $emit(eventName)을 사용하여 이벤트를 트리거
<div id="app">
<app-header v-on:pass="logText"></app-header>
<app-content v-on:increase="increaseNum" v-bind:props-num="num"></app-content>
</div>
...
<script>
var appHeader = {
template: '<button v-on:click="passEvent">Click me</button>',
methods: {
passEvent: function () {
this.$emit('pass');
}
}
}
var appContent = {
template: '<button v-on:click="addNumber">Add {{propsNum}}</button>',
props: ['propsNum'],
methods: {
addNumber: function() {
this.$emit('increase')
}
}
}
new Vue({
el: "#app",
components: {
'app-header': appHeader,
'app-content': appContent
},
data: {
num: 10
},
methods: {
logText: function () {
console.log("click!!");
},
increaseNum: function() {
this.num++;
}
}
});
</script>
같은 레벨 컴포넌트 간의 통신
- 같은 레벨 컴포넌트 간에는 직접적인 데이터 전달이 불가능하다.
- 상위 컴포넌트로 이벤트 전달 후, 상위 컴포넌트에서 다른 하위 컴포넌트로 데이터를 전달해준다.
<div id="app">
<app-header v-bind:props-num="num"></app-header>
<app-content v-on:pass="deliverNum"></app-content>
</div>
<script>
let appHeader = {
template: '<div>header-{{ propsNum }}</div>',
props: ['propsNum']
}
let appContent = {
template: '<div>Content<button v-on:click="passNum">pass</button></div>',
methods: {
'passNum': function () {
this.$emit('pass', 10);
}
}
}
new Vue({
el: "#app",
components: {
'app-header': appHeader,
'app-content': appContent
},
data: {
num: 0
},
methods: {
deliverNum: function(value) {
console.log(value);
this.num = value;
}
}
});
</script>
반응형
'Study > Vue.js' 카테고리의 다른 글
[Vue.js] 09 ES6 (0) | 2021.09.24 |
---|---|
[Vue.js] 07 SFC(Single File Component) (0) | 2021.09.24 |
[Vue.js] 05 Template (0) | 2021.09.23 |
[Vue.js] 03 Router (0) | 2021.09.23 |
[Vue.js] 01 Instance (0) | 2021.09.23 |