What is Vue.js?
Vue는 사용자 인터페이스를 만들기 위한 프로그레시브 프레임워크로 점진적으로 채택할 수 있도록 설계되어 있는 프레임워크이다. Vue의 핵심 라이브러리는 Vue로 구현한 뷰 레이어만 적용할 수 있기 때문에 다른 라이브러리나 기존 프로젝트와의 통합이 매우 쉽고, 여러 현대적인 개발 도구와 Vue를 지원하는 라이브러리를 함께 사용하면 정교한 싱플 페이지 어플리케이션도 쉽게 구현할 수 있다.
Quick Start
1. CDN
Vue는 프로토 타이핑이나 단순 학습 목적을 위해 최신 버전을 쉽게 사용해 볼 수 있도록 CDN으로도 스크립트를 제공하고 있다.
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
만약 특정 버전의 빌드 파일을 사용해야 하는 경우라면 아래와 같이 특정 버전의 빌드 파일을 추가할 수 있다.
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
ES 모듈을 사용할 수 있는 환경이라면 아래와 같이 ES 모듈 호환 빌드 파일을 사용할 수 있다.
<script type="module">
import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.esm.browser.js'
</script>
2. NPM
대규모 애플리케이션을 구축하는 경우에는 NPM을 설치하도록 권장한다.
npm install vue
위 명령어로 Vue를 설치하고 나면 다음과 같이 Vue를 실행할 수 있는 최소한의 환경으로 구성된 package-lock.json 파일이 생성되고 관련된 모듈들이 설치된다.
3. CLI
Vue는 단일 페이지 애플리케이션을 빠르게 구축할 수 있는 Vue CLI를 통해 최신 프론트엔드 워크 플로우를 위해 사전 구성된 빌드 설정을 제공하고 있는데 Vue CLI는 핫 리로드와 저장 시 린트 체크 및 프로덕션 준비가 된 빌드 시스템으로 시작하고, 실행하는데는 몇 분밖에 걸리지 않지만 Node.js와 관련된 빌드 도구에 대한 사전 지식이 필요하다.
-Vue CLI 설치하기
Vue CLI는 npm 또는 yarn 명령어로 설치할 수 있다.
npm install -g @vue/cli
yarn global add @vue/cli
-Vue CLI 업데이트하기
Vue CLI는 다음의 명령어로 업데이트 할 수 있다.
npm update -g @vue/cli
yarn global upgrade --latest @vue/cli
-Vue CLI로 새 프로젝트 생성하기
Vue CLI로 프로젝트를 생성하는 경우 default(babel, eslint)를 선택하면 가장 기본적인 설정으로 프로젝트가 생성되고, 옵션을 언제든지 추가할 수 있다.
vue create 프로젝트명
프로젝트를 생성한 후에는 다음의 명령어로 로컬 서버를 실행해주면 된다.
npm run serve
Vue 기초 문법
선언적 렌더링과 디렉티브
Vue는 간단한 템플릿 구문으로 다음과 같이 DOM의 내부에서 데이터를 선언적으로 렌더링 할 수 있는 방법을 제공하고 있다.
<div id="app">
{{ message }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello, World'
}
})
</script>
선언적 렌더링은 문자열 템플릿을 렌더링하는 것과 매우 유사하지만, Vue의 내부에서는 실제로 더 많은 작업을 하면서 데이터와 DOM을 연결시켜 반응형인 상태를 유지하게 된다.
이렇게 Vue는 #app과 같은 단일 DOM 요소에 연결되어 DOM 요소 자체를 제어하는데, HTML은 엔트리 포인트의 역할만을 하고 다른 모두 작업은 새롭게 생성된 Vue 인스턴스 내에서 발생한다는 특징이 있다.
디렉티브
<div id="app-2">
<span v-bind:title="message">title 속성에 동적 바인딩</span>
</div>
<script>
var app2 = new Vue({
el: '#app-2',
data: {
message: new Date() + '에 로드됨'
}
})
</script>
위 코드를 실행한 후 콘솔 창을 통해 확인해보면 엘리먼트의 title 속성에 값이 바인딩 되었다는 것을 알 수 있는데, 여기서 사용된 v-bind라는 속성은 Vue에서 제공하는 특수 속성으로 디렉티브라고 부른다.
디렉티브는 Vue에서 제공하는 특수 속성임을 나타내는 v- 라는 접두어가 붙는데, 렌더링 된 DOM에는 이 속성이 나타나지 않지만, 해당 엘리먼트는 v-bind에 적용된 특수한 반응형 동작을 하게 된다.
조건문과 반복문
Vue는 v-bind 외에도 v-if, v-for와 같은 다양한 디렉티브를 통해 엘리먼트를 제어할 수 있는데, 조건에 따른 동작을 제어하고 싶은 경우에는 v-if라는 디렉티브를 사용하면 엘리먼트의 동작을 쉽게 제어할 수 있다.
- v-if
<div id="app-3">
<p v-if="seen">This element is shown.</p>
</div>
<script>
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
</script>
위 코드는 app3.seen의 상태 설정에 따라 엘리먼트가 보여지거나, 보여지지 않도록 제어하는 코드인데, 브라우저의 콘솔 창에서 app3.seen = false와 같이 상태를 변경해보면 엘리먼트가 사라지는 것을 확인할 수 있다.
여기서 v-if와 v-for와 같은 디렉티브는 텍스트와 속성뿐만 아니라 DOM의 구조에도 데이터를 바인딩할 수 있음을 보여주는데, 이 때 엘리먼트가 Vue에 삽입, 업데이트, 제거될 때 자동으로 트랜지션 효과를 적용할 수 있는 강력한 전환 효과 시스템도 사용할 수 있다.
- v-for
만약 여러 개의 반복 작업이 필요한 경우라면 v-for 디렉티브를 사용하면 되는데, v-for 디렉티브는 배열의 데이터를 바인딩하여 리스트의 목록을 표시하도록 만들 수 있다.
<div id="app-4">
<ol>
<li v-for="item in lists">
{{ item.text }}
</li>
</ol>
</div>
<script>
var app4 = new Vue({
el: '#app-4',
data: {
lists: [
{ text: 'List 01' },
{ text: 'List 02' },
{ text: 'List 03' }
]
}
})
</script>
사용자 입력 핸들링
v-on과 v-model은 사용자와 앱의 상호작용을 위해 사용하는 디렉트브로 v-on은 Vue 인스턴스에서 메소드를 호출하는 이벤트 리스너와를 연결하고, v-model은 사용자의 입력과 앱 상태를 양방향으로 바인딩해준다.
- v-on
v-on 디렉티브로 Vue 인스턴스에서 메소드를 호출하는 이벤트 리스너를 연결하는 방법은 DOM을 건드리지 않고 앱의 상태만을 업데이트 하는데, 모든 DOM 조작은 Vue에 의해 처리된다.
<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">거꾸로</button>
</div>
<script>
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello, World!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
</script>
- v-model
Vue는 양식에 대한 입력과 앱 상태를 양방향으로 바인딩하는 v-model 디렉티브를 제공하는데, 이 디렉티브를 사용하면 다음의 예제와 같이 사용자의 입력을 엘리먼트에 즉시 반영할 수 있다.
<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div>
<script>
var app6 = new Vue({
el: '#app-6',
data: {
message: '메세지를 입력해주세요.'
}
})
</script>
컴포넌트 구성하기
컴포넌트란 작고 독립적이며 재사용할 수 있는 조각들로, 대규모 애플리케이션을 구축할 수 있게 해주는 추상적인 개념이다.
이 컴포넌트는 Vue의 중요한 개념 중에 하나인데, 거의 모든 유형의 애플리케이션 인터페이스는 컴포넌트 트리로 추상화할 수 있다.
Vue에서 컴포넌트는 미리 정의된 옵션을 가진 Vue 인스턴스로, Vue에서 컴포넌트를 등록하는 방법은 다음과 같다.
Vue.component('list-item', {
template: '<li>할일 목록입니다.</li>'
})
var app = new Vue(...)
위와 같이 컴포넌트를 정의하면, 해당 컴포넌트를 다른 컴포넌트의 템플릿에 추가할 수 있다.
<ol>
<list-item></list-item>
</ol>
그런데 앞에서와 같이 단순한 형태로 컴포넌트를 정의하면 똑같은 내용의 엘리먼트만을 렌더링하게 되기 때문에 컴포넌트를 정의할 때 부모 영역의 데이터를 자식 컴포넌트에게 전달할 수 있도록 prop이라는 속성을 제공해 줄 필요가 있다.
Vue.component('list-item', {
props: ['label'],
template: '<li>{{ label.text }}</li>'
})
위와 같이 prop 속성을 추가해주면 list-item 컴포넌트는 "label"로 정의된 prop을 통해 사용자 정의 속성과 같은 것을 입력받을 수 있는데, 다음과 같이 v-bind를 사용하여 각각의 반복되는 list-item을 컴포넌트에 전달할 수 있다.
<div id="app-7">
<ol>
<list-item v-for="item in lists" v-bind:label="item" v-bind:key="item.id"></list-item>
</ol>
</div>
<script>
Vue.component('list-item', {
props: ['label'],
template: '<li>{{ label.text }}</li>'
})
var app7 = new Vue({
el: '#app-7',
data: {
lists: [{
id: 0,
text: 'List 01'
},
{
id: 1,
text: 'List 02'
},
{
id: 2,
text: 'List 03'
}
]
}
})
</script>
코드에서는 list-item을 HTML의 엘리먼트처럼 사용하고 있는데, 이렇게 정의된 컴포넌트를 사용하면서 v-bind를 통해 컴포넌트의 "label"이라는 속성에 리스트이 각 객체를 전달하고, v-bind:key라는 디렉티브로 lists의 각 객체에 있는 id 값을 전달해 키로 사용하고 있다.
이렇게 대규모 애플리케이션에서는 개발을 보다 쉽게 관리할 수 있도록 전체 앱을 컴포넌트 단위로 나누는 것이 필수적이기 때문에 컴포넌트의 개념을 잘 알아둘 필요가 있다.
-사용자 정의 엘리먼트
Vue 컴포넌트는 Web Components Spec의 일부인 사용자 정의 엘리먼트와 유사한데, 다음과 같은 중요한 차이가 있다.
(1) Vue 컴포넌트는 지원되는 모든 브라우저에서 폴리필 없이도 일관된 방식으로 동작하며, 필요한 경우 기본 사용자 정의 에릴먼트 내에 래핑이 가능하다
(2) Vue 컴포넌트는 컴포넌트 간 데이터의 흐름, 사용자 정의 이벤트와 통신 등 기본 사용자 지정 엘리먼트에서 사용할 수 없었던 중요한 기능을 제공한다.