Vue Architecture

Component 단위로 개발하는 Vue


Vue는 컴포넌트 단위로 개발할 수 있다. 컴포넌트(Component)란, html, css, javascript를 1개의 파일 단위로 나눠서 개발하는 것을 말한다. Vue에서는 이를 싱글 파일 컴포넌트라고 하는데, UI 단위로 나눠서 개발하여, 코드의 재사용 측면에서 좋다.

즉, Vue.js는 컴포넌트를 조합해 전체 애플리케이션을 만든다. 이때, 컴포넌트들은 부모-자식 관계를 갖는 트리구조로 작성할 수 있다.

Vue 프로젝트를 생성하게 되면, 다양한 파일이 만들어진다.


index.html


index.html: 어플리케이션 전체의 뼈대가 되는 html 파일이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>what</title>
</head>
<body>
<noscript>
<strong>We're sorry but what doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>


main.js


main.js: Vue 인스턴스를 생성해주는 파일이다.

1
2
3
4
5
6
7
8
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
render: h => h(App),
}).$mount('#app')

이 자바스크립트 파일은 new 연산자를 사용해서 Vue 인스턴스를 생성해준다. Vue는 기본적으로 인스턴스를 생성하여 개발을 하는데, 컴포넌트 단위로 개발을 할 경우, main.js에서 new 연산자로 Vue 인스턴스를 생성하게 해주고, 각 컴포넌트에서 각 UI에 맞게 인스턴스를 활용해서 컴포넌트를 개발한다.

render에서 h() 안에 있는 ‘App’은 첫 화면에 뿌려질 Vue 컴포넌트를 의미한다.

1
render: h => h(App)

$mount() 안에 있는 ‘#app’은 id를 ‘app’으로 가지고 있는 html 태그를 의미한다. 이 태그로 마운트한다는 것인데, 마운트한다는 것은 위 App 컴포넌트를 이 html 태그(id를 ‘app’으로 가지고 있는 태그)에 연결시킨다는 의미이다.

1
$mount('#app')

즉, 위 index.html에 있는 <div id="app"></div> 안으로 App 컴포넌트를 연결(넣는다)한다는 뜻이다.


component.vue


component.vue: 재사용성을 고려해 UI 단위로 개발하는 vue 파일이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
name: 'app',
components: {
HelloWorld
}
}
</script>

<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

component는 위와 같이 3가지로 구성되어 있다.

  • template
  • script
  • style

Vue의 MVVM 패턴에 따라 나누면 다음과 같은 3가지로 구성되어 있다.

  • ViewModel
  • View
  • Model


1. ViewModel

Vue.js에서 모든 Vue 인스턴스는 ViewModel인데, 이 ViewModel은 Model과 View 사이에서 양방향 데이터 바인딩을 해줌으로써, 동기화 역할을 한다. ViewModel은 Vue 생성자 혹은 하위 클래스들에 의해 인스턴스화된다.

1
var vm = new Vue({ /* options */ })


2. View

Vue.js는 DOM 기반의 템플릿을 사용하는데, View의 실제 돔(DOM)은 Vue instance에 의해 관리된다. 각 Vue 인스턴스는 해당 DOM 요소에 연관된다. Vue 인스턴스가 생성되면 필요한 데이터 바인딩을 설정하는 동안 루트 요소의 모든 자식 노드를 반복적으로 탐색한다. 뷰가 컴파일이 되면 데이터 변경에 반응할 수 있게 된다.

1
2
3
4
5
6
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<p>{{ msg }}</p>
</div>
</template>

즉, 해당 HTML 컴포넌트 범위(해당 DOM 요소가 담긴 템플릿)를 Vue 인스턴스의 vm.$el에 설정한다. 뷰는 Vue 인스턴스가 생성 될 때, 컴파일 되며 뷰모델의 다양한 동작 기능들이 바인딩 된다. 그렇게 됨으로써 뷰의 변경이 감지되면 뷰모델이 이를 감지하여 반응할 수 있게된다. 또한, 뷰의 변경은 집단적으로, 비동기로 실행되기 때문에 높은 성능을 발휘한다.


3. Model

Vue.js에서 모델은 단순히 자바스크립트 객체 혹은 데이터 객체로 표현할 수 있다. 데이터 객체의 프로퍼티를 조작하면 이를 관찰하는 뷰 인스턴스가 변경을 알린다. Vue.js는 ES5 getter/setters로 데이터 객체의 프로퍼티를 변환한다. 그렇기에 뷰를 변경하기 위해 Vue에 명시적으로 신호를 보낼 필요가 없다. 그리고, 각 뷰 인스턴스는 데이터 객체에 있는 모든 프로퍼티들을 프록시한다.

1
2
3
4
5
6
7
8
9
10
11
12
export default {
name: 'app',
components: {
HelloWorld
},
// Model
data: function() {
return {
msg: 'hello'
}
}
}