컴포넌트란?
컴포넌트 그 자체로 제 기능을 하며 재사용할 수 있는 컴포넌트로 구성된 대규모 응용 프로그램을 구축할 수 있게 해주는 추상적 개념이다.
- 기본 HTML Element를 확장하여 재사용 가능한 코드를 캡슐화할 수 있게 해준다.
- 컴포넌트는 Vue의 컴파일러에 의해 동작이 추가된 사용자 지정 Element이다. 경우에 따라 is 속성으로 확장된 원시 HTML Element로 나타낼 수 있다.
- 거의 모든 유형의 응용 프로그램 인터페이스를 컴포넌트 트리로 추상화할 수 있다. Vue에서 컴포넌트는 미리 정의된 옵션을 가진 Vue인스턴스이다.
- Vue 컴포넌트는 Vue 인스턴스이기하므로, 모든 옵션 객체를 사용할 수 있다. (루트에만 사용하는 옵션은 제외)
- Vue 인스턴스와 같은 라이프사이클 훅을 사용할 수 있다.
장점
- 뛰어난 재사용성
- 반복되어 사용되는 UI와 기능을 컴포넌트로 만들어놓으면 여러 곳에서 재사용할 수 있어 생산성읖 높일 수 있음
- 테스트 용이
- 컴포넌트 단위로 기능 테스트가 가능. Karma나 Mocha 같은 단위 테스트 도구를 이용하여 손쉽게 테스트가 가능하다.
- 디버깅이 편하다.
- Vue devtools와 같은 도구를 이용해 컴포넌트 단위로 전달된 속성(props)을 손쉽게 살펴볼 수 있고, 부모 컴포넌트로 전달된 이벤트 정보를 손쉽게 파악할 수 있다.
컴포넌트 조합
Vue 컴포넌트는 속성과 이벤트로 부모와 자식 컴포넌트가 서로 상호작용을 한다.
속성[props]: 부모 → 자식
컴포넌트들은 속성(props)을 통해 자식 컴포넌트로 정보를 전달할 수 있다.
- 단방향: 부모 컴포넌트에서 자식 컴포넌트로만 전달
- 양방향으로 데이터 전달은 가능하지만 애플리케이션의 복잡도를 높여 유지보수가 어려우므로 지양한다.
이벤트: 자식 → 부모
자식 컴포넌트는 부모 컴포넌트로 이벤트를 발신할 수 있다.
- 자식 컴포넌트에서 사용자 정의 이벤트를 정의하고 이벤트를 발생시키면 부모 컴포넌트에서 이벤트 핸들러 메서드를 호출하도록 작성
컴포넌트 사용하기
# 전역등록
전역 컴포넌트를 등록하려면, Vue.component(tagName, options)를 사용한다.
Vue.component([tagName], [options])
1) tagName: 컴포넌트를 사용할 태그명
- 태그명은 대소문자를 구분하지 않기 때문에 케밥 표기법(kebob casting)을 따르는 것이 좋다.
- 파스칼 표기법(pascal casing): 두 단어 이상으로 연결될 때, 단어의 시작을 대문자로함. 첫글자를 대문자로 표기. ex) YouLikeVue
- 케밥 표기법(kebob casting): 모든 단어가 소문자로 시작하고, 단어와 단어 사이에는 "-"로 연결된 방식. ex) you-like-vue
- 카멜 표기법(camel casing): 두 단어 이상으로 연결될 때, 단어의 시작을 대문자로 함. 첫글자는 소문자로 표기. ex) youLikeVue
2) options: 컴포넌트에서 렌더링할 template등을 설정
선언한 컴포넌트 사용: <component-tag-name></component-tag-name>
등록되면, 컴포넌트는 인스턴스의 템플릿에서 커스텀 Element로 사용 가능. root Vue 인스턴스를 인스턴스화하기 전에 컴포넌트가 등록되어있는지 확인해야한다.
<!-- html -->
<div id="example">
<my-component></my-component>
</div>
<!-- JavaScript -->
// 등록
Vue.component('my-component', {
template: '<div>사용자 정의 컴포넌트 입니다!</div>'
})
// 루트 인스턴스 생성
// root Vue 인스턴스를 인스턴스화하기 전에 컴포넌트가 등록되어있는지 확인해야한다.
new Vue({
el: '#example'
})
# 지역 등록
컴포넌트를 components 인스턴스 옵션으로 등록하여 다른 인스턴스/컴포넌트의 범위에서만 사용할 수 있도록 컴포넌트를 등록할 수 있다.
동일한 캡슐화는 디렉티브와 같은 다른 등록 가능한 Vue 기능에도 적용된다.
var Child = {
template: '<div>사용자 정의 컴포넌트 입니다!</div>'
}
new Vue({
// ...
components: {
// <my-component> 는 상위 템플릿에서만 사용할 수 있습니다.
'my-component': Child
}
})
# 컴포넌트 템플릿 작성
1) template 태그
<template>태그를 이용하여 템플릿 작성 후 템플릿 id로 참조해서 사용함.
<!-- html -->
<template id="helloTemplate">
<div>Hello World!</div>
</template>
<!-- JavaScript -->
Vue.component('hello-component', {
template: '#helloTemplate'
});
2) 템플릿 문자열을 직접 지정
가독성과 유지보수성이 떨어지므로 해당 방식은 지양해야한다.
Vue.component('my-component', {
template: '<div>사용자 정의 컴포넌트 입니다!</div>'
})
3) X-Template
템플릿을 정의하는 또 다른 방법으로, text/x-template유형의 스크립트 Element 내부에 ID로 템플릿을 참조한다.
- 큰 템플릿이나 매우 작은 응용 프로그램의 데모에는 유용 할 수 있지만 템플릿을 나머지 컴포넌트 정의와 분리하기 때문에 피해야한다.
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
<!-- --->
Vue.component('hello-world', {
template: '#hello-world-template'
})
# 컴포넌트 작성 시 주의 사항
1) DOM 템플릿 구문 작성 시 주의 사항
is 속성 <select>태그와 같이 내부에 올 수 있는 태그가 정해져있는 경우에 컴포넌트를 사용할 경우 컴포넌트의 태그를 찾지 못해 구문 분석 단계에서 DOM 요솨 올바르지 않다고 판단하여 제대로 렌더링하지 못하는 문제가 발생한다. 해당 문제를 해결하기 위해 is 속성을 사용한다.
- script type="text/x-template"> 태그 안에서 사용되거나, .vue확장자를 사용하는 단일 파일 컴포넌트를 작성하는 경우에는 굳이 is특성을 사용하지 않아도 된다.
- <template>태그를 사용할 때는 is속성을 사용해야 한다.
- 대상 태그는 <ul>, <ol>, <table>, <select>등이 있다.
is 속성 사용
<select>
<option is="option-component"></option>
<option is="option-component"></option>
</select>
X-Template 사용
<script type="txt/javascript">
Vue.component('option-component', {
template : '<option>hello</option>'
})
</script>
<script type="text/x-template" id="selectTemplate">
<select>
<option-component></option-component>
<option-component></option-component>
</select>
</script>
2) 컴포넌트에서 data옵션은 반드시 함수로 작성
data, methods, computed, watch 옵션과 같은 대부분의 Vue인스턴스 옵션을 컴포넌트 수준에서도 사용 가능. 컴포넌트에서 data 옵션은 반드시 함수로 작성하고 함수 내부에서 객체를 반환해야 한다.
- 컴포넌트 기반으로 개발할 때 data옵션은 각 컴포넌트의 로컬 상태(Local State)를 관리하기 위한 용도로만 사용되므로, 동일한 객체 참조가 발생하지않아야 한다.
- 하나의 컴포넌트를 애플리케이션에서 여러 번 사용할 경우에 모두 다른 상태 정보를 가져야하기 때문에 단순한 객체 값으로 작성하면 객체가 참조형 값이므로 모두 동일한 값을 참조하게 되기 때문이다.
참고 : Vue.js 퀵스타트
'javascript > Vue' 카테고리의 다른 글
Vue devtools 설치 및 사용 (0) | 2021.07.25 |
---|---|
Vue.js 컴포넌트 (심화) (0) | 2021.04.13 |
Vue 다이어리 만들기(Vue Diary) - vuex,vue-router,element-ui (0) | 2020.07.21 |