오늘은 뷰의 컴포넌트에 대해 알아보겠습니다. 뷰는 앱이 실행될 때 루트 컴포넌트에서 시작하여 컴포넌트들의 트리로 구성됩니다. 이 말은 곧 화면을 기능단위로 쪼개는 것을 의미합니다. 잘 만들어진 컴포넌트는 재사용성을 높이고, 유지 보수하기 쉬워집니다.
규모가 작은 애플리케이션을 설계 할 때는 강박적으로 적용할 필요는 없지만, 보통 회원가입, 게시물 CRUD를 정도 이상의 웹 사이트를 만들 땐
그럼 컴포넌트 개발에 앞서 어떻게 설계해야 할 지 먼저 알아보겠습니다.
FIRST 원칙
Keep it (F)ocused.
Keep it (I)ndependent.
Keep it (R)eusable.
Keep it (S)mall.
Keep it (T)estable.
F(단일 책임 원칙) : 컴포넌트는 하나의 기능을 수행하는 데 집중해야 한다.
=> 뷰 컴포넌트의 data, methods, props, template 등이 개발자가 정의한 기능을 구현하는 데 집중
I(독립적인) : 다른 컴포넌트의 도움을 받지 않아야 한다.
=> 이 컴포넌트가 기능을 수행하기 위해 this.$parent, this.$ref로 다른 컴포넌트의 값에 의존하면 안된다
R(재사용가능한): 컴포넌트는 재사용이 가능해야 한다.
=> 잘 설계된 컴포넌트는 ‘추천 검색어’, ‘최근 검색어’ 와 같이 비슷한 동작을 하는 기능을 구현할 때 TabComponent라는 하나의 모듈로 두 기능 이상을 구현할 수 있어야 합니다.
S(작은): 가능한 작게
=> 애초에 작게 기능을 정의하고, 코딩 라인 수도 가능한 심플하게 해야합니다.
T(테스트가 가능한): 디버깅이 쉬운 컴포넌트를 작성해야 한다. 앞의 4가지 원칙적용
뷰 컴포넌트
그럼 본격적으로 뷰에서 컴포넌트를 통한 개발을 진행해보겠습니다. 크게 두 가지 방식이 있습니다.
js파일 또는 스크립트로 컴포넌트를 정의
1
2
3
4
5
6
7
8
9
var appHeader = {
template: '<h1>Header Component</h1>'
}
new Vue({
components: {
'app-header': appHeader
}
})
1
2
3
4
// 전역 컴포넌트 등록
Vue.component('app-header', {
template: '<h1>Header Component</h1>'
});
위 두 방식처럼 변수에 template, (data, methods …)을 정의하고 Vue 인스턴스에 등록하는 방식과Vue.component()로 전역 컴포넌트로 등록하는 방식이 있습니다.
아니면 다음과 같이 javascript 모듈 import, export로 컴포넌트를 개발하는 방식도 있습니다.
1
2
3
4
5
6
7
8
9
<!-- index.html -->
<body>
<div class='container'>
<tabs></tabs>
</div>
...
</body>
<template id='tabs'>탭 템플릿 입니다</template>
1
2
3
4
5
6
// components/TabComponent.js
export default {
template: '#tabs',
props: [...]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// app.js
import TabComponent from "./components/TabComponent.js"
...
new Vue({
el: '#app',
...
components: {
'tabs': TabComponent
}
})
이런식으로 메인 페이지에 해당하는 html 파일에 , 뷰 인스턴스가 생성되는 메인 자바스크립트 파일에는 인스턴스 내부에 components 모듈을 등록, 탭 컴포넌트 파일에서는 export 키워드로 template을 바인딩 해주고 기타 props, data, methods 등 을 정의합니다.
여기까지가 첫 번째 방식입니다. 컴포넌트로 개발을 했지만 html, 메인 자바스크립트, 컴포넌트 파일을 왔다 갔다 하는 방식이 많이 혼란스럽습니다. 그래서 뷰는 vue-cli를 통해 단일 파일 컴포넌트 개발 방식을 지원합니다.
단일 파일 컴포넌트
위의 예제처럼 .js 파일을 만드는 것이 아닌, html, css, javascript가 모두 포함된 .vue 파일 통해 코딩하는 방식입니다. vue-cli를 설치했고, vue init simple-webpack으로 기본적을 폴더를 생성했다고 가정하겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// TabComponent.vue
<template>
<ul class="tabs">
</ul>
</template>
<script>
export default{
props: [...]
}
</script>
<style>
// 사용하지 않으면 삭제
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// App.vue
<template>
...
<tabs></tabs>
...
</template>
<script>
import TabComponent from './components/TabComponent.vue'
export default {
name: 'app',
...
components: {
'tabs' : TabComponent
}
}
</script>
조금 복잡해 보일 수 있지만, 원리를 이해하면 간단합니다. 우선 vue파일을 사용하지 않았을 때랑 비교해보면 template id를 지정할 필요가 없습니다. 왜냐하면 html파일이 아닌 vue 파일 안에 태그로 해당 컴포넌트의 템플릿이 지정되었기 때문입니다. 그리고 보시다시피
정리
오늘은 뷰 컴포넌트를 설계할 때 고려할 사항과 실제로 코드로 어떻게 구현되는지 알아보았습니다. 구현을 단계별로 보시면서 저렇게 까지 왜 해야하나 생각이 드실 수 있습니다. 하지만 대규모 개발에서는 앞서 말씀드린 FIRST 원칙을 적용하지 않으면 서비스의 확장, 유지보수성이 떨어지기에 이를 지키려는 노력으로 생각하면 좋을 것 같습니다.