Skip to content

Commit 920091a

Browse files
committed
Add vue with vuex vuerouter
1 parent 07fb1a0 commit 920091a

File tree

1 file changed

+277
-0
lines changed

1 file changed

+277
-0
lines changed
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
---
2+
layout: post
3+
title: "vue와 vue-router, vuex 함께 사용하기"
4+
date: 2017-01-08 08:45:31 +0530
5+
categories: update
6+
author: "ChangJoo Park"
7+
excerpt: "vue의 컴패니언 라이브러리를 사용하는 방법을 빠르게 살펴봅니다."
8+
---
9+
10+
# Vue의 컴패니언 라이브러리 (vue-router, vuex)
11+
12+
이 글은 vuex 와 vue-router를 **적용**하는 방법에 대해서 알아봅니다. 매우 간략한 내용만 다루고 있으므로 더 자세한 사용 방법에 대한 내용은 [vuex 한국어 문서](https://vuex.vuejs.org/kr/)[vue-router 한국어 문서](https://router.vuejs.org/kr/)를 읽어보세요.
13+
14+
## vue-cli
15+
16+
vue-cli는 기본적으로 vue만 포함하고 있습니다. [vuejs 템플릿 github 조직](https://github.com/vuejs-templates)은 vue-cli의 템플릿을 간결하게 유지하고 싶기 때문에 vuex 또는 vue-router를 포함하려 하지 않고 있습니다. 이와 관련한 논의는 [이 이슈](https://github.com/vuejs-templates/webpack/pull/347)[이 이슈](https://github.com/vuejs-templates/webpack/pull/296#discussion_r82073211)를 읽어보세요.
17+
18+
하지만 매번 vuex와 vue-router를 추가하는 것은 매우 까다로운 일이기 때문에 템플릿을 만들었습니다. [이 저장소](https://github.com/ChangJoo-Park/webpack)를 살펴보세요. 간단한 사용법은 아래에 있습니다. 수정하려면 fork 하여 사용하시면 됩니다. 현재 standard와 airbnb 스타일을 모두 지원하고 있습니다.
19+
20+
```terminal
21+
$ npm install -g vue-cli
22+
$ vue init changjoo-park/webpack my-project
23+
$ cd my-project
24+
$ npm install
25+
$ npm run dev
26+
```
27+
28+
자신만의 템플릿을 만드는 것은 [사용자 정의 템플릿 작성해보기](https://github.com/vuejs-kr/vue-cli#사용자-정의-템플릿-작성해보기)를 읽어보세요
29+
30+
## vue-router 와 vuex
31+
32+
### 프로젝트 구조
33+
34+
위 템플릿으로 만든 `my-project`를 살펴보겠습니다.
35+
36+
![폴더 구조](http://i.imgur.com/3szmkHP.png)
37+
38+
vue-cli로 만든 `my-project` 앱의 `src` 디렉터리의 구조입니다. 추가된 것은 `routes.js``vuex` 디렉터리입니다.
39+
40+
### vue-router
41+
42+
`main.js` 를 살펴보겠습니다.
43+
44+
```javascript
45+
// The Vue build version to load with the `import` command
46+
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
47+
import Vue from 'vue'
48+
import Router from 'vue-router'
49+
import App from './App'
50+
import routes from './routes'
51+
// Styles
52+
import './assets/styles/styles.scss'
53+
54+
Vue.use(Router)
55+
const router = new Router({
56+
mode: 'history',
57+
scrollBehavior: () => ({ y: 0 }),
58+
routes
59+
})
60+
61+
/* eslint-disable no-new */
62+
new Vue({
63+
router,
64+
...App
65+
}).$mount('#app')
66+
```
67+
68+
중요한 부분은 **4번**, **6번**, **10번 ~ 15번**, **19번** 코드 입니다.
69+
70+
vue-router와 라우트에 대한 내용(routes.js)을 가져오고(**4번**, **6번**), Vue에 vue-router를 사용할 것을 알려줍니다.(**10번**) 그리고 router 인스턴스를 만든 후(**11번** ~ **15번**) 이 것을 실제 사용할 Vue에 넣어 인스턴스를 만듭니다.(**19번**)
71+
72+
**11번** ~ **15번** 코드의 `mode``scrollBehavior`는 공식 문서의 [HTML5 히스토리 모드](https://router.vuejs.org/kr/essentials/history-mode.html)[스크롤 동작](https://router.vuejs.org/kr/advanced/scroll-behavior.html)을 읽어보세요.
73+
74+
`main.js` 파일에서 살펴보지 않은 `routes.js` 파일을 살펴보겠습니다.
75+
76+
```javascript
77+
import HomePage from 'components/HomePage'
78+
import CounterPage from 'components/CounterPage'
79+
80+
export default [
81+
{
82+
path: '/',
83+
name: 'home-page',
84+
component: HomePage
85+
},
86+
{
87+
path: '/counter',
88+
name: 'counter-page',
89+
component: CounterPage
90+
},
91+
{
92+
path: '*',
93+
redirect: '/'
94+
}
95+
]
96+
```
97+
98+
앞에서 설명하지 않았지만 `changjoo-park/webpack` 템플릿에는 **HomePage****CounterPage** 컴포넌트가 포함되어 있습니다.
99+
100+
`path``name` 그리고 `component`를 지정해주면 해당 `path`에 맞는 컴포넌트를 화면에 그려줍니다. 지정하지 않은 `path`를 걸러내기 위해 맨 아래 라우트를 추가하였습니다. 자세한 내용은 공식 vue-router 가이드의 [시작하기](https://router.vuejs.org/kr/essentials/getting-started.html)를 보시면 됩니다.
101+
102+
`App.vue` 단일 파일 컴포넌트의 템플릿을 보겠습니다.
103+
104+
```html
105+
<template>
106+
<div id="app">
107+
<ul class="navigation">
108+
<li><router-link v-bind:to="{ name: 'home-page' }">Home</router-link></li>
109+
<li><router-link v-bind:to="{ name: 'counter-page' }">Counter</router-link></li>
110+
</ul>
111+
<router-view></router-view>
112+
</div>
113+
</template>
114+
```
115+
116+
`App.vue` 템플릿에서 보셔야할 부분은 `router-link``router-view` 입니다. `router-link`는 라우트를 지정해주고, `router-view`는 지정된 라우트에 맞는 컴포넌트를 화면에 그려줍니다.
117+
118+
#### 새 페이지를 추가하려면
119+
120+
새 페이지를 추가하는 방법은 다음 순서로 하시면 됩니다.
121+
122+
- 새 페이지를 위한 컴포넌트를 만듭니다.
123+
- `routes.js`에 라우트를 정의해 줍니다.
124+
- 새로 만든 페이지로 이동할 수 있도록 `router-link`를 만듭니다.
125+
126+
127+
128+
### vuex
129+
130+
vuex 는 앱 전체에서 공유할 수 있는 데이터센터 입니다. 부모 컴포넌트와 자식 컴포넌트 사이에 데이터를 주고 받을 때 불편함을 해소하는데 큰 역할을 합니다.
131+
132+
vuex 디렉터리 구조 입니다.
133+
134+
![](http://i.imgur.com/bpfZUTz.png)
135+
136+
vuex의 자세한 내용은 [vuex 시작하기](https://vuex.vuejs.org/kr/intro.html)를 읽고 보시면 더 이해가 쉽습니다. vuex의 `main.js`파일에 해당하는 `store.js` 부터 살펴보겠습니다.
137+
138+
```javascript
139+
import Vue from 'vue'
140+
import Vuex from 'vuex'
141+
import * as actions from './actions'
142+
import * as getters from './getters'
143+
import modules from './modules'
144+
145+
Vue.use(Vuex)
146+
147+
export default new Vuex.Store({
148+
actions,
149+
getters,
150+
modules,
151+
strict: true
152+
})
153+
```
154+
155+
vue-router를 추가하는 것과 동일한 흐름으로 이해하시면 됩니다. vuex 구조에서 `actions`, `getters`(state), `modules`(mutations)를 Vuex의 `store`에 추가하여 vuex인스턴스를 만드는 코드입니다.
156+
157+
![vuex 구조](https://vuex.vuejs.org/kr/images/vuex.png)
158+
159+
160+
161+
우선 `mutation-types.js`를 보겠습니다. vuex가 어떤 종류의 `mutation`을 정의한 파일입니다.
162+
163+
```javascript
164+
export const DECREMENT_MAIN_COUNTER = 'DECREMENT_MAIN_COUNTER'
165+
export const INCREMENT_MAIN_COUNTER = 'INCREMENT_MAIN_COUNTER'
166+
```
167+
168+
카운터를 증가시키고 감소시키는 조작만 있으면 됩니다.
169+
170+
이제 실제 조작에 대한 구현을 보겠습니다. `counters.js` 파일입니다. modules 디렉터리의 `index.js`는 modules에 있는 module을 export 해주는 유틸 스크립트입니다. 한번 살펴보세요.
171+
172+
```javascript
173+
import * as types from '../mutation-types'
174+
175+
const state = {
176+
main: 0
177+
}
178+
179+
const mutations = {
180+
[types.DECREMENT_MAIN_COUNTER] (state) {
181+
state.main--
182+
},
183+
[types.INCREMENT_MAIN_COUNTER] (state) {
184+
state.main++
185+
}
186+
}
187+
188+
export default {
189+
state,
190+
mutations
191+
}
192+
```
193+
194+
`state`가 있고, `mutations`가 있습니다. state는 실제 counter의 상태를 보관합니다. 그리고 mutations는 위에서 정의한 조작 요청이 오면 카운터를 증가 / 감소 시킵니다.
195+
196+
mutation을 실제로 발생시키려면 action이 필요합니다. action은 vue 컴포넌트에서 `dispatch`를 이용해 호출하는 메소드입니다.
197+
198+
```javascript
199+
import * as types from './mutation-types'
200+
201+
export const decrementMain = ({ commit }) => {
202+
commit(types.DECREMENT_MAIN_COUNTER)
203+
}
204+
205+
export const incrementMain = ({ commit }) => {
206+
commit(types.INCREMENT_MAIN_COUNTER)
207+
}
208+
```
209+
210+
`actions`는 백엔드 API와 통신하는 역할을 가지지만 여기서는 백엔드가 없는 앱이므로 바로 mutation을 `commit`을 이용해 요청합니다.
211+
212+
이제 컴포넌트에서 사용할 상태를 호출하기 위한 `getters`(state) 를 살펴보겠습니다. 파일은 `getters.js` 입니다.
213+
214+
```javascript
215+
export const mainCounter = state => state.counters.main
216+
```
217+
218+
템플릿에 포함된 애플리케이션은 Counter 앱에 대한 상태만 보관하므로 **mainCounter**라는 **getter**만 있습니다 .state의 counters의 main을 반환하는 역할을 합니다. 이 곳에 `filter``map`등을 이용해 원하는 내용만 사용할 수 있습니다.
219+
220+
vuex가 준비되었으므로 counter 앱을 만들어보겠습니다. 가장 먼저, App 컴포넌트에 vuex를 사용한다고 알려줘야 합니다.
221+
222+
`App.vue``script` 블럭입니다.
223+
224+
````javascript
225+
<script>
226+
import store from 'src/vuex/store'
227+
228+
export default {
229+
store,
230+
name: 'app'
231+
}
232+
</script>
233+
````
234+
235+
vuex의 store를 가져와 App 컴포넌트에 추가했습니다. 이제 앱의 어디든 `this.$store`를 이용해 vuex에 접근할 수 있습니다.
236+
237+
`CounterPage.vue` 파일에 카운터 앱이 있습니다. 따로 컴포넌트로 분리해 보세요. 템플릿을 만들기 쉽게하기 위해 `CounterPage.vue`에 넣은 것 입니다. 코드를 살펴보겠습니다.
238+
239+
템플릿 코드 입니다.
240+
241+
```html
242+
<div class="counter-number">
243+
{{counter}}
244+
</div>
245+
<button class="counter-button" v-on:click="incrementCounter">+</button>
246+
<button class="counter-button" v-on:click="decrementCounter">-</button>
247+
```
248+
249+
스크립트 코드입니다.
250+
251+
```javascript
252+
computed: {
253+
counter () {
254+
return this.$store.getters.mainCounter
255+
}
256+
},
257+
methods: {
258+
incrementCounter () {
259+
this.$store.dispatch('incrementMain')
260+
},
261+
decrementCounter () {
262+
this.$store.dispatch('decrementMain')
263+
}
264+
}
265+
```
266+
267+
`computed``getters`에 지정해 놓은 **mainCounter**를 가져왔습니다. 그리고 `mehotds`에는 `actions`에 추가한 액션들을 호출하는 코드가 있습니다. action을 실행하는 것은 `dispatch`입니다. 자세한 내용은 [Vuex가이드의 액션](https://vuex.vuejs.org/kr/actions.html)을 읽어보세요.
268+
269+
#### 새 모듈을 추가하려면
270+
271+
- mutation-types.js 에 어떤 변이가 필요한지 추가하세요.
272+
- modules 디렉터리에 사용할 모듈 파일을 만들고, state와 mutations을 추가하세요.
273+
- `actions.js`에 mutation을 호출할 메소드를 만드세요.
274+
- `getter.js`에 컴포넌트에서 사용할 상태를 추가하세요.
275+
- 컴포넌트에서 `computed`에 상태를, `methods`에 액션을 호출할 `dispatch`를 추가하세요.
276+
277+
[vuex의 가이드](https://vuex.vuejs.org/kr/intro.html)에 더 자세한 내용이 있습니다. 꼭 읽어보세요.

0 commit comments

Comments
 (0)