2장 인스턴스와 컴포넌트
작성
2장. 화면 개발의 필수 단위
- 인스턴스: 레고를 조립하는 기본 판
- 컴포넌트: 레고 블록
1) 인스턴스
- 화면 개발을 위해 필수적으로 생성하는 기본 단위
(1) 뷰 인스턴스 정의와 속성
new Vue({
el: '#app',
data: {
message:'value from data'
}
})
new Vue(): 뷰 인스턴스 생성자- 뷰 인스턴스의 정의된 프로퍼티
el: 뷰로 만든 화면이 그려지는 시작점을 나타내는 돔 요소template: 마크업 요소 정의methods: 이벤트, 화면 동작과 같은 화면 로직을 제어하는 메서드 정의created: 인스턴스가 생성되자마자 실행할 로직 정의data: 바인딩할 데이터key:value형식으로 정의
(2) 뷰 인스턴스의 유효 범위
- 인스턴스의 유효 범위: 뷰 인스턴스를 생성하면 HTML 특정 범위 안에서만 옵션 속성들이 나타난다.
new Vue({
el:'#app',
})
<div id="app">
<!-- Vue 인스턴스의 유효범위 -->
</div>
(3) 뷰 인스턴스 라이프 사이클

1. beforeCreate
- data, methods 속성이 인스턴스에 정의되어 있지 않고 돔과 같은 화면 요소에도 접근할 수 없다.
2. created
- data, methods 속성 접근하여, 로직 실행 가능
- 인스턴스가 화면에 부착되기 전이기 때문에, template 속성에 정의된 돔 요소에 접근할 수 없다.
3, beforeMount
- 인스턴스르 부착하기 전에 호출되는 단계이다.
- render() 함수가 호출되기 직전의 로직을 추가하기 좋다.
4. mounted
- template 속성에 정의한 화면 요소에 접근 할 수 있어 화면 요소 제어하는 로직 수행하는 단계이다.
- 돔에 인스턴스가 부착되자마자 바로 호출되기 때문에 하위 컴포넌트나 외부 라이브러리에 의해 추가된 하면 요소들이 최종 HTML 코드로 변환되는 시점과 다를 수 있다.
5. beforeUpdate
- 데이터 관찰: 뷰의 반응성을 제공하기 위해
$watch속성으로 감시한다. - 데이터가 변경되면 가상 돔으로 화면을 다시 그리기 전에 호출되는 단계이다.
- 변경 예정인 데이터에 접근할 수 있어, 관련 로직을 미리 넣을 수 있다.
6. updated
- 데이터가 변경되고 나서 가상 돔으로 다시 화면을 그리고 나서 실행되는 단계이다.
- 데이터 변경으로 인한 화면 요소 변경까지 완료된 시점이므로, 데이터 변경 후 화면 요소 제어와 관련된 로직을 추가하기 좋은 단계이다.
7. beforeDestroy
- 뷰 인스턴스가 뷰 인스턴스가 없어지기 직전에 호출되는 단계, 아직 인스턴스에 접근할 수 있어 인스턴스의 데이터를 삭제하기 좋은 단계다.
8. destroyed
- 뷰 인스턴스에 정의한 모든 속성이 제거되고 하위에 선언한 인스턴스들 모두 파괴된다.
new Vue({
el:'#app',
data:{
message:'Hello'
},
beforeCreate(){
},
created(){
},
mounted(){
this.message = 'changed'
},
updated(){
console.log('updated')
}
})
2) 컴포넌트
- 컴포넌트는 블록이다. 조합하여 화면을 구조화하여 일괄적인 패턴으로 구성할 수 있다.
(1) 전역 컴포넌트
Vue.component('global-component',{
template:'<div>전역 컴포넌트<div>'
});
Vue.component():뷰 생성자 컴포넌트 등록- 인스턴스 객체 생성
- 특정 화면 요소에 인스턴스 부착
- 인스턴스 내용 반환:
<component>=><div>
(2) 지역 컴포넌트
- 지역 컴포넌트는 인스턴스 유효 범위를 따른다.
new Vue({
el:'#app',
components:{
'local-component': {
template:'<div>지역 컴포넌트</div>'
}
}
})
- 지역 컴포넌트는 해당
el의 특정 범위 안에서만 컴포넌트가 유효하다.
<div id='app1'>
<global-component></global-component>
<local-component></local-component>
</div>
// 전역 컴포넌트
// 지역 컴포넌트
<div id='app2'>
<global-component></global-component>
<local-component></local-component>
</div>
<script>
// 전역 컴포넌트
Vue.component('global-component',{
template:'<div>전역 컴포넌트<div>'
});
new Vue({
el:'#app1',
components:{
'local-component': {
template:'<div>지역 컴포넌트</div>'
}
}
})
new Vue({
el:'#app2',
})
</script>
3) 뷰 컴포넌트 통신
- 컴포넌트는 유효 범위가 독립적이기 때문에 다른 컴포넌트의 값을 직접적으로 참조할 수 없다.
- 따라서 뷰에서 정의한 상위 => 하위 컴포넌트 데이터 전달 방법을 따라야 한다.
- 상위 컴포넌트에서는
props전달을, 하위 컴포넌트에서는이벤트 발생을 전달한다.
(1) props: 상위에서 하위 컴포넌트로 데이터 전달하기
Vue.component('child-component',{
props: ['propsdata']
})
<child-component v-bind:props propsdata="상위 컴포넌트의 데이터"></child-component>
- 사용 예시
<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:"psssed from Parent Component"
}
})
</script>
- 뷰 인스턴스 자체가 상위 컴포넌트가 되어, 새로 등록된 컴포넌트는 자식 컴포넌트가 된다.
(2) $emit(): 하위에서 상위 컴포넌트로 이벤트 전달하기
- 하위 컴포넌트는 이벤트 발생을 통해 상위 컴포넌트와 통신한다.
- 이벤트 발생:
$emit() - 이벤트 수신:
v-on:
// 이벤트 발생
this.$emit('이벤트명')
// 이벤트
<child-com v-on:이벤트명="상위 컴포넌트 메서드명"></child-com>
- 사용 예시
<child-com v-on:show-log="printLog"></child-com>
<!-- `show-log` 이벤트 수신 후 상위 컴포넌트 메서드 이용 -->
<script>
Vue.component('child-com',{
template:'<button v-on:click="showLog">show</button>',
methods:{
showLog() {
this.$emit('show-log') // 'show-log' 이벤트 발생
}
}
})
new Vue({
el:'#app',
methods:{
printLog(){
console.log('parent 컴포넌트 실행')
}
}
})
</script>
this.$emit('이벤트')in 하위 컴포넌트의 메서드v-on:이벤트="상위 컴포넌트 메서드"in 하위 컴포넌트 등록 태그
(3) 같은 레벨의 컴포넌트 간 통신
- 상위에서 하위로만 데이터를 전달해야 하는 통신 규칙을 따르기 때문에 옆 컴포넌트에 값을 전달하려면, 하위에서 공통 상위 컴포넌트로 이벤트를 전달한 후 공통 상위 컴포넌트에서 2개의 하위 컴포넌트에 props을 내려 보내야 한다.
- 하지만 이런 통신 구조는 상위 컴포넌트가 필요 없음에도 불구하고 같은 레벨을 통신하기 위해 강제로 상위 컴포넌트를 두어야 한다.
(4) 이벤트 버스: 관계 없는 컴포넌트 간 통신
- 상, 하위 관계를 유지하고 있지 않아도 컴포넌트간 데이터를 전달할 수 있다.
- 이벤트 버스를 위한 추가 인스턴스를 생성한다.
<div id="sibling1"></div>
<div id="sibling2"></div>
<script>
var eventBus = new Vue();
new Vue({
el: '#sibling1',
template: '<button v-on:click="showLog">버튼</button>',
methods: {
showLog() {
eventBus.$emit('triggerEventBus', 100);
},
},
});
new Vue({
el: '#sibling2',
created() {
eventBus.$on('triggerEventBus', (value) => console.log(value));
},
});
</script>
- 컴포넌트가 많아지면 어디서 어디로 보냈는지 관리하기 힘들기 때문에 이는 뷰엑스 상태관리 도구를 통해 해결해야 한다.