나도뷰 1
Vue?
Vue
란 사용자 인터페이스를 만들기 위한Progressive Framework
MVVM 디자인 패턴
- MVC(Model, View, Controller) 패턴의 변형으로, View 의 추상화를 만드는 것이 핵심인 패턴
- Model
App
에서 사용되는데이터
와 그 데이터를처리
하는 부분- 비즈니스 로직과 유효성 검사, 데이터를 포함하는
App
의 도메인 모델
- View
- 사용자에게 보여지는 구조, 레이아웃, 형태 등을 정의하는
UI
부분 - 애니메이션 같은
UI
로직을 포함하되 비즈니스 로직은 포함하지 않음
- 사용자에게 보여지는 구조, 레이아웃, 형태 등을 정의하는
- View Model
View
를 위한Model
(추상화 된 View)View
를 나타내기 위한Model
이자,View
를 나타내기 위해데이터 처리
를 하는 부분View
가 사용할 메소드와 필드를 구현하고,View
에게 상태 변화를 알리는 것
// View
<div id="app">
<span></span>
</div>
// View Model
new Vue({
el: "#app",
data: data
})
// View
data = {
text: "Hello World!"
}
MVVM 디자인 패턴의 특징
Model
에 의존성이 없는View
,View
와 비즈니스 로직의 철저한 분리View Model
이Model
과View
사이의어댑터
로서, 변경이 생겼을 때 변경을 최소화할 수 있음- 규모가 작은 프로젝트에서 사용할 경우 코드의 양이 많아질 수 있음
Vue.js 기초
Vue 인스턴스
- 모든
Vue App
은Vue 인스턴스
를 만드는 것으로 시작
new Vue()
- 인스턴스 안에는 미리 정의되어 있는
속성과 메서드(API)
들이 있음 -
아래 6개는 보편적인
Vue 인스턴스 옵션
으로, 전체 목록은 API reference 에서 확인 가능- el
Vue 인스턴스
가 그려질 화면의 HTML 태그 (DOM 엘리먼트)new
를 이용한 인스턴스 생성 시에만 사용
- template: 화면에 표시할 요소
- data: 화면에 띄울 데이터 속성
- methods
- 화면의 동작과 이벤트 로직을 제어하는 옵션
- VM 인스턴스를 통해 직접 접근하거나 디렉티브 표현식에서 사용 가능
- created
- 인스턴스가 작성된 후 동기적으로 호출됨
Vue
의 라이프사이클과 관련된 속성- 마운트 시작 전에 호출되므로
$el
속성을 사용할 수 없음
- watch
data
에서 정의한 속성이 변화했을 때 추가 동작을 수행할 수 있게 정의Vue 인스턴스
는 인스턴스 생성 시 객체의 각 항목에 대해$watch()
를 호출
new Vue({ el: , template: , data: , methods: , created: , watch: })
- el
- Computed
data
속성이 변했을 때, 이를 감지하고 자동으로 다시 연산함- 인자를 받지 않는 특징이 있음
HTTP 통신
과 같은 로직을 정의하지 않음
Vue 인스턴스 라이프 사이클
Vue Data Binding
- 단방향 데이터 바인딩
Vue 인스턴스
의 data 객체가 가지고 있는 정보를HTML 코드
로 바인딩methods
내의 함수로 데이터를 변경하면 즉시 값이 변함- Vue 인스턴스 -> Template
- 양방향 데이터 바인딩
Directive
,v-
접두사를 가진 속성을 이용- 데이터에 있는 값이
View
에 나타나고,View
에서 값을 바꾸면 데이터의 값도 같이 바뀜 - Vue 인스턴스 <-> Template
<div id="app">
<!-- v-model 을 사용해 양방향 데이터 바인딩이 가능하도록 구현 -->
<!-- v-model 은 v-bind:value + v-on:input 로 이해할 수 있음 -->
<input type="text" v-model="name">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el: "#app",
data: {
name: "infiduk"
}
})
</script>
재사용 가능한 Component
// 컴포넌트 생성
Vue.component('app-header', {
template: '<h1>Header Component</h1>'
});
// 등록한 컴포넌트를 화면에 표시하는 방법
<div id="app">
<app-header></app-header>
</div>
// 위 소스는 아래와 같이 표시됨
<div id="app">
<h1>Header Component</h1>
</div>
Vue
에서Component
는 전역, 지역Component
로 등록할 수 있음Component
를 생성할 때,data
는 반드시 함수여야 함 (인스턴스 마다 데이터를 구분하기 위함)
// 전역 컴포넌트 생성
Vue.component('app-header', {
template: '<h1>Header Component</h1>'
});
// 지역 컴포넌트 생성
var appHeader = {
template: '<h1>Header Component</h1>'
}
new Vue({
components: {
'app-header': appHeader
}
})
Component 에서 통신하는 방법
- props
- 상위 Component -> 하위 Component
- 하위 Component 의 template 에서 상위 Component 의 데이터를 직접 참조할 수 없고,
props
옵션을 통해 상위 Component 의 데이터를 하위 Component 로 전달할 수 있음
// propsdata 라는 이름으로 props 를 받을 것이라고 명시적으로 선언
var childComponent = {
props: ['propsdata'],
template: '<p></p>'
}
new Vue({
el: '#app',
components: {
'child-component': childComponent
},
data: {
message: 'hello vue.js'
}
})
// childComponent 의 props 이름으로 상위 Component 의 message 를 전달
<div id="app">
<child-component :propsdata="message"></child-component>
</div>
- event
- 하위 Component -> 상위 Component
같은 레벨의 Component
끼리 통신할 때도 사용- 이벤트를 전송하는
$emit
과, 이벤트를 감지하는$on
을 이용하여 통신
// 하위 Component 에 메소드 선언
var childComponent = {
methods: {
sendEvent: function() {
this.$emit('update');
}
}
}
// 상위 Component 에서 사용
new Vue({
el: '#app',
components: {
'child-component': childComponent
},
methods: {
showAlert: function() {
alert('event received');
}
}
})
// 하위 컴포넌트 에서 update 라는 이벤트가 발생되면,
// 상위 컴포넌트의 showAlert 메소드가 호출됨
<div id="app">
<child-component @update="showAlert"></child-component>
</div>
Router
Vue 라이브러리
를 이용하여 싱글 페이지 앱을 구현할 때 사용
// 네비게이션을 위한 router-link Component 사용
// 실제 화면에서는 <a> 태그로 변형되어 나타남
<router-link to="/foo">Go To Foo</router-link>
// Route 에 맞는 Component 렌더링
<router-view></router-view>
// Route Component 정의
// 다른 파일에서 import 한 후 가져올 수도 있음
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// Route 정의
// 각 Route 는 반드시 Component 와 매핑되어야 함
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 옵션으로 router 인스턴스 생성
const router = new VueRouter({
// routes: routes 의 줄임
routes
})
// 아래와 같이 router 인스턴스를 생성할 수도 있음
// mode: URL의 해쉬 값 제거 속성
// routes: 라우팅 할 URL과 Component 값 지정
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
})
// 루트 인스턴스를 만들고 mount
const app = new Vue({
router
}).$mount('#app')
// router 접근
this.$router
Single File Component
HTML
,CSS
,JS
코드를 한 파일에서 관리하는 방법
<!-- .vue 파일 구조 -->
<template>
<!-- html (뷰 컴포넌트의 표현단, 템플릿 문법) -->
</template>
<script>
// javascript (뷰 컴포넌트 내용)
</script>
<style>
/* css (뷰 템플릿의 스타일링) */
</style>
참고
- Vue.js 2 시작하기 (도서)
- 디자인 패턴 - MVC, MVVM
- MVVM 패턴
- 양방향 데이터 바인딩
- Vue Guide
- Cracking Vue.js