본문 바로가기

Javascript/Vue

Vue.js 2.x 가이드 따라치기 Overview (Vue Document가 그렇게 잘 되어있다던데..)

반응형

Vue.js

Vue는 따로 블로그로 정리할 필요없이 Document가 잘 되어있는 것으로 알려져있다.

(심지어 vue.js 한국 사용자 모임에서 많은 프로젝트들(vue-router, vue-loader등)을 번역해놔서 문서들이 어색함이 없이 술술 읽힌다.)

하지만 Document가 아무리 잘 되어있어도 읽기만 하고 넘어가거나 그런가보다 하고 넘어가면 의미가 없다.

한국어 번역 작업을 열심히 해주셨으니 잘 읽어보고 실습을 해보고 나름대로 느낀 점을 정리하면 좋겠다고 생각했다.


Vue.js 가이드 따라하기

Vue.js의 장점은 여러 블로그에 많으니 생략한다. 또한 여러가지 설치 방법(환경 설정)이 있지만 생략한다.

대신 CDN으로 가져와서 해보거나 jsfiddle에서 계속 테스트한다. (추후 spring boot와 연동해볼 것이다.)

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

참고로 위의 사진은 jsfiddle에서 제공하는 vue.js 보일러플레이트 코드다.

가이드의 '시작하기'를 몰라도 그냥 쭉 읽고 위의 보일러플레이트 코드를 보면 이해할 수 있다.

기본 구조

<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: '안녕하세요 Vue!'
}
})

CDN을 가져와서 위의 짧은 코드만 쳤을 뿐인데 잘 적용됐다.

마치 부트스트랩(Bootstrap)을 쓰는 것처럼 간단하고 좋다는 느낌을 받았다.

자바스크립트 코드에서 new Vue를 통해 Vue 객체를 생성하는데, 객체 생성할 때 'el', 'data' 같은 사전에 정의된 옵션 값을 적용해서 어떤 값(data)이 어떤 곳(el)에 사용될지 지정하는 것 같다.

단순히 html 파일에서는 {{ }} 문법으로 값을 가져와서 데이터와 DOM이 바인딩되게 하는 것 같다.

추후에 이런 옵션들에 대해서 알아볼 것이다. (역시 API에 한국어로 잘 정리되어 있다)

디렉티브

<div id="app-2">
<span v-bind:title="message">
내 위에 잠시 마우스를 올리면 동적으로 바인딩 된 title을 볼 수 있습니다!
</span>
</div>
var app2 = new Vue({
el: '#app-2',
data: {
message: '이 페이지는 ' + new Date() + ' 에 로드 되었습니다'
}
})

v-bind:title 이라는 것이 나오는데 'v-' 라는 접두사(prefix)가 붙어 속성들을 디렉티브 라고 한다.

v-bind:title의 의미는 해당 태그에 마우스를 올리면(hover) 작게 나오는 글?에 바인딩되서 "message"가 나오는 것 같다.

조건, 반복문

var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})

v-if 디렉티브로 조건문을 걸 수 있다.

1
2
3
4
5
<div id="app-3">
  <p v-if="seen">seen이 true면 나를 볼 수 있어요</p>
  <p v-else>seen이 false면 나를 볼 수 있어요</p>
</div>
 


위 처럼 v-else도 걸 수 있나보다.. jsfiddle의 보일러플레이트 코드를 보고 알았다.

설마 v-else-if도 있을까? 하고 찾아보니 vue 2.1.0 버전부터 생겼다고 한다.

<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>

위 처럼 사용하면 v-else-if를 적용할 수 있다.

<div id="app-4">
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
</div>
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: 'JavaScript 배우기' },
{ text: 'Vue 배우기' },
{ text: '무언가 멋진 것을 만들기' }
]
}
})

for문을 이용한 반복은 위와 같이 한다. v-for="todo in todos"라고 써서 todos로 오는 배열을 반복하는 듯하다. for-in 구문 정도로 알고 넘어간다.

이벤트

<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">메시지 뒤집기</button>
</div>
var app5 = new Vue({
el: '#app-5',
data: {
message: '안녕하세요! Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})

v-on 디렉티브를 사용해서 인스턴스에 이벤트 리스너를 달 수 있는 것 같다.

v-on:click으로 해당 버튼이 클릭되면 "reverseMessage" 라는 메서드가 실행되는 것 같다.

참고로 DOM을 직접 건드리지 않고 Vue에 의해 처리되고 업데이트 된다.

양방향 바인딩

<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div>
var app6 = new Vue({
el: '#app-6',
data: {
message: '안녕하세요 Vue!'
}
})

v-model 디렉티브는 양방향 바인딩을 할 수 있게 한다.

input의 v-model의 값을 "message" 데이터로 설정하게 되면 message 값이 연동될 뿐만아니라 직접 데이터도 변경해서 실시간 반영될 수 있게 한다.

새로하는 프로젝트에서 config 설정을 실시간으로 바꿀 수 있게 해야하는데 이 기능을 사용할 수 있을까 고민해봤다.

그런데 너무 실시간이라서 오히려 설정 변경은 따로 request로 처리하는 것이 좋아보인다고 느꼈다.

대신 실시간 데이터를 보여주고 그래프에서 x, y축 값 같은 것(range)을 반영하는 것에는 활용할 수 있겠다고 생각했다.


컴포넌트 매커니즘 

위에서 간단히 살펴본 내용은 Vue 객체를 생성하는 옵션, 디렉티브 활용에 대한 것이고, 실 사용에서 중요한 부분은 컴포넌트로 활용하는 부분이다.

// todo-item 이름을 가진 컴포넌트를 정의합니다
Vue.component('todo-item', {
template: '<li>할일 항목 하나입니다.</li>'
})
<ol>
<!-- todo-item 컴포넌트의 인스턴스 만들기 -->
<todo-item></todo-item>
</ol>

Vue.component로 컴포넌트를 생성할 수 있다. 'todo-item'이라는 컴포넌트를 등록하고 옵션으로 template을 설정했다.

그러면 등록한 이름으로 태그를 만들면 해당 태그에는 template이 들어가는 구조다.

기본 구조는 위와 같지만 위에 처럼 template을 static하게 만들면 해당 태그(<todo-item>)는 계속 같은 값을 가진다.

따라서 값을 다양하게 줄 수 있어야 하는데 그 방법으로 "prop"을 사용해서 부모 영역의 데이터를 자식 컴포넌트에 넣어주는 방법이 있다.

<div id="app-7">
<ol>
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id">
</todo-item>
</ol>
</div>

Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})

var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Whatever else humans are supposed to eat' }
]
}
})

테스트 해보니까 Vue.component로 등록하는 코드가 위에 나와야 한다.

id가 app-7인 부모 영역의 데이터 groceryList 배열을 props를 통해서 자식 객체에서 사용할 수 있게 했고 배열의 인덱스의 값을 'todo'로 지정하고 template에서 {{ todo.text }} 를 표시하게 했다.

그 후 html 값에서 todo-item 태그안에 v-for를 통해 반복해서 item으로 값들을 하나하나 꺼냈고 v-bind:todo를 통해 todo가 각 item으로 설정되게 했다. v-bind:key는 잘 모르겠다.

가이드에서는 1. 2. 3. 이런식으로 id index가 붙는데 jsfiddle에서는 그냥 텍스트 리스트만 나온다...


이렇게 간단하게 "시작하기" 부분을 마쳤고 이후에 계속 알아나갈 예정이다.

* 참고로 틀린 부분이 아주 많을 수 있다. 잘못된 부분있으면 지적해줘서 올바른 공유를 했으면 좋겠다.


참고 사이트

https://kr.vuejs.org/v2/guide/index.html

반응형