瀏覽代碼

Translate vuex in Korean. (#517)

* Add Korean directory

* installation

* intro

* getting started

* state

* getters

* Add Korean

* mutation

* actions

* modules

* structure

* strict

* forms

* hot-reload

* plugins

* api

* testing

* summary

* update intro

* Update translations
ChangJoo Park(박창주) 8 年之前
父節點
當前提交
aaaf5991b8

+ 1 - 0
docs/LANGS.md

@@ -3,4 +3,5 @@
 * [2.0 - Français](fr/)
 * [2.0 - Русский](ru/)
 * [2.0 - 日本語](ja/)
+* [2.0 - 한국어(Korean)](ko/)
 * [1.0 Docs](old/)

+ 1 - 0
docs/ko/README.md

@@ -0,0 +1 @@
+{% include "./SUMMARY.md" %}

+ 22 - 0
docs/ko/SUMMARY.md

@@ -0,0 +1,22 @@
+# Vuex
+
+> 참고: 이 문서는 vuex@2.x 을 기준으로 합니다.
+
+- [1.0 버전 문서를 보려면?](https://github.com/vuejs/vuex/tree/1.0/docs)
+- [릴리즈 노트](https://github.com/vuejs/vuex/releases)
+- [설치](installation.md)
+- [Vuex가 무엇인가요?](intro.md)
+- [시작하기](getting-started.md)
+- 핵심 컨셉
+  - [상태](state.md)
+  - [Getters](getters.md)
+  - [변이](mutations.md)
+  - [액션](actions.md)
+  - [모듈](modules.md)
+- [애플리케이션 구조](structure.md)
+- [플러그인](plugins.md)
+- [Strict 모드](strict.md)
+- [폼 핸들링](forms.md)
+- [테스팅](testing.md)
+- [핫 리로딩](hot-reload.md)
+- [API 레퍼런스](api.md)

+ 175 - 0
docs/ko/actions.md

@@ -0,0 +1,175 @@
+# 액션
+
+액션은 변이와 유사합니다. 몇가지 다른 점은,
+
+- 상태를 변이시키는 대신 액션으로 변이에 대한 커밋을 합니다.
+- 작업에는 임의의 비동기 작업이 포함될 수 있습니다.
+
+간단한 액션을 등록합시다.
+
+``` js
+const store = new Vuex.Store({
+  state: {
+    count: 0
+  },
+  mutations: {
+    increment (state) {
+      state.count++
+    }
+  },
+  actions: {
+    increment (context) {
+      context.commit('increment')
+    }
+  }
+})
+```
+
+액션 핸들러는 저장소 인스턴스의 같은 메소드들/프로퍼티 세트를 드러내는 컨텍스트 객체를 받습니다. 그래서 `context.commit`을 호출하여 변이를 커밋하거나 `context.state`와 `context.getters`를 통해 상태와 getters에 접근 할 수 있습니다. 나중에 [모듈](modules.md)에서 이 컨텍스트 객체가 저장소 인스턴스 자체가 아닌 이유를 알 수 있습니다.
+
+실제로 (특히 `commit`를 여러 번 호출해야하는 경우)코드를 단순화하기 위해 ES2015 [전달인자 분해](https://github.com/lukehoban/es6features#destructuring)를 사용합니다.
+
+``` js
+actions: {
+  increment ({ commit }) {
+    commit('increment')
+  }
+}
+```
+
+### 디스패치 액션
+
+액션은 `store.dispatch` 메소드로 시작됩니다.
+
+``` js
+store.dispatch('increment')
+```
+
+처음 볼 때는 이상해 보일 수 있습니다. 카운트를 증가 시키려면 `store.commit('increment')`를 직접 호출하면 어떻습니까? 음, **돌연변이는 동기적** 이어야 한다는 것을 기억하십니까? 액션은 그렇지 않습니다. 액션 내에서 **비동기** 작업을 수행 할 수 있습니다.
+
+``` js
+actions: {
+  incrementAsync ({ commit }) {
+    setTimeout(() => {
+      commit('increment')
+    }, 1000)
+  }
+}
+```
+
+액션은 동일한 페이로드 타입과 객체 스타일의 디스패치를 지원합니다.
+
+``` js
+// 페이로드와 함께 디스패치
+store.dispatch('incrementAsync', {
+  amount: 10
+})
+
+// 객체와 함께 디스패치
+store.dispatch({
+  type: 'incrementAsync',
+  amount: 10
+})
+```
+
+액션의 좀 더 실용적인 예는 **비동기 API 호출** 과 **여러 개의 변이를 커밋** 하는 장바구니 결제입니다.
+
+``` js
+actions: {
+  checkout ({ commit, state }, products) {
+    // 장바구니에 현재있는 항목을 저장하십시오.
+    const savedCartItems = [...state.cart.added]
+
+    // 결제 요청을 보낸 후 장바구니를 비웁니다.
+    commit(types.CHECKOUT_REQUEST)
+
+    // 상점 API는 성공 콜백 및 실패 콜백을 받습니다.
+    shop.buyProducts(
+      products,
+      // 요청 성공 핸들러
+      () => commit(types.CHECKOUT_SUCCESS),
+      // 요청 실패 핸들러
+      () => commit(types.CHECKOUT_FAILURE, savedCartItems)
+    )
+  }
+}
+```
+
+비동기 작업의 흐름을 수행하고 커밋하여 작업의 사이드이펙트(상태 변이)을 기록합니다.
+
+### 컴포넌트 내부에서 디스패치 액션 사용하기
+
+`this.$store.dispatch('xxx')`를 사용하여 컴포넌트에서 액션을 디스패치하거나 컴포넌트 메소드를 `store.dispatch` 호출에 매핑하는 `mapActions` 헬퍼를 사용할 수 있습니다 (루트 `store` 주입 필요) :
+
+``` js
+import { mapActions } from 'vuex'
+
+export default {
+  // ...
+  methods: {
+    ...mapActions([
+      'increment' // this.increment()을 this.$store.dispatch('increment')에 매핑
+    ]),
+    ...mapActions({
+      add: 'increment' // this.add()을 this.$store.dispatch('increment')에 매핑
+    })
+  }
+}
+```
+
+### 액션 구성하기
+
+액션은 종종 비동기적 입니다. 그러면 액션이 언제 완료되는지 어떻게 알 수 있습니까? 더 중요한 것은, 복잡한 비동기 흐름을 처리하기 위해 어떻게 여러 작업을 함께 구성 할 수 있습니까?
+
+가장 먼저 알아야 할 점은 `store.dispatch`가 트리거 된 액션 핸들러에 의해 반환된 Promise를 처리 할 수 있으며 Promise를 반환한다는 것입니다.
+
+``` js
+actions: {
+  actionA ({ commit }) {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        commit('someMutation')
+        resolve()
+      }, 1000)
+    })
+  }
+}
+```
+
+이렇게 할 수 있습니다.
+
+``` js
+store.dispatch('actionA').then(() => {
+  // ...
+})
+```
+
+그리고 안에 또 다른 액션을 사용할 수 있습니다.
+
+``` js
+actions: {
+  // ...
+  actionB ({ dispatch, commit }) {
+    return dispatch('actionA').then(() => {
+      commit('someOtherMutation')
+    })
+  }
+}
+```
+
+마지막으로, JavaScript 기능인 [async/await](https://tc39.github.io/ecmascript-asyncawait/)를 사용하면 다음과 같은 작업을 구성 할 수 있습니다.
+
+``` js
+// getData() 및 getOtherData()가 Promise를 반환한다고 가정합니다.
+actions: {
+  async actionA ({ commit }) {
+    commit('gotData', await getData())
+  },
+  async actionB ({ dispatch, commit }) {
+    await dispatch('actionA') // actionA가 끝나기를 기다립니다.
+    commit('gotOtherData', await getOtherData())
+  }
+}
+```
+
+> `store.dispatch`가 다른 모듈에서 여러 액션 핸들러를 트리거하는 것이 가능합니다. 이 경우 반환 된 값은 모든 트리거 된 처리기가 완료 되었을 때 처리되는 Promise입니다.

+ 178 - 0
docs/ko/api.md

@@ -0,0 +1,178 @@
+# API 레퍼런스
+
+### Vuex.Store
+
+``` js
+import Vuex from 'vuex'
+
+const store = new Vuex.Store({ ...options })
+```
+
+### Vuex.Store 생성자 옵션
+
+- **state**
+
+  - 자료형: `Object`
+
+    Vuex 저장소의 루트 상태 객체 입니다.
+
+    [상세](state.md)
+
+- **mutations**
+
+  - 자료형: `{ [type: string]: Function }`
+
+    저장소에 변이를 등록하십시오. 핸들러 함수는 항상 첫 번째 전달인자로 `state`를 받습니다 (모듈에 정의 된 경우 모듈 로컬 상태가됩니다). 두 번째 `payload` 전달인자가 있으면 처리합니다.
+
+    [상세](mutations.md)
+
+- **actions**
+
+  - 자료형: `{ [type: string]: Function }`
+
+    저장소에 액션을 등록하십시오. 핸들러 함수는 다음 속성을 노출하는 `context` 객체를받습니다.
+
+    ``` js
+    {
+      state,     // store.state와 같습니다. 또는 모듈에 있는 경우 로컬 상태
+      rootState, // store.state와 같습니다. 모듈 안에만 존재합니다
+      commit,    // store.commit와 같습니다.
+      dispatch,  // store.dispatch와 같습니다.
+      getters    // store.getters와 같습니다.
+    }
+    ```
+
+    [상세](actions.md)
+
+- **getters**
+
+  - 자료형: `{ [key: string]: Function }`
+
+    저장소에 getter를 등록하십시오. getter 함수는 다음 전달인자를 받습니다.
+
+    ```
+    state,     // 모듈에 정의 된 경우 모듈 로컬 상태가됩니다.
+    getters,   // store.getters와 같습니다.
+    rootState  // store.state와 같습니다.
+    ```
+
+    등록된 getter는 `store.getters`에 노출됩니다.
+
+    [상세](getters.md)
+
+- **modules**
+
+  - 자료형: `Object`
+
+    저장소에 병합될 하위 모듈을 포함하는 객체 입니다.
+
+    ``` js
+    {
+      key: {
+        state,
+        mutations,
+        actions?,
+        getters?,
+        modules?
+      },
+      ...
+    }
+    ```
+
+    각 모듈은 루트 옵션과 비슷한 `state` 와 `mutations` 를 포함 할 수 있습니다. 모듈의 상태는 모듈의 키를 사용하여 저장소의 루트 상태에 연결됩니다. 모듈의 변이와 getter는 모듈의 로컬 상태를 루트 상태 대신 첫 번째 전달인자로 받으며 모듈 액션의 `context.state`도 로컬 상태를 가리 킵니다.
+
+    [상세](modules.md)
+
+- **plugins**
+
+  - 자료형: `Array<Function>`
+
+    저장소에 적용 할 플러그인 함수의 배열입니다. 플러그인은 저장소를 유일한 전달인자로 받아들이고 아웃바운드 데이터 지속성, 로깅 또는 디버깅을 위한 변이를 감시하거나 (인바운드 데이터 (예: 웹 소켓 또는 관찰 가능 항목)의 디스패치 변이) 감시할 수 있습니다.
+
+    [상세](plugins.md)
+
+- **strict**
+
+  - 자료형: `Boolean`
+  - 기본값: `false`
+
+    Vuex 저장소를 strict 모드로 변경합니다. strict 모드에서 변이 핸들러 외부의 Vuex 상태에 대한 임의의 변이는 오류를 발생시킵니다.
+
+    [상세](strict.md)
+
+### Vuex.Store 인스턴스 속성
+
+- **state**
+
+  - 자료형: `Object`
+
+    루트 상태. 읽기 전용
+
+- **getters**
+
+  - 자료형: `Object`
+
+    등록된 getters 입니다. 읽기 전용.
+
+### Vuex.Store 인스턴스 메소드
+
+- **`commit(type: string, payload?: any) | commit(mutation: Object)`**
+
+  변이를 커밋합니다. [상세](mutations.md)
+
+- **`dispatch(type: string, payload?: any) | dispatch(action: Object)`**
+
+  액션을 디스패치 합니다. 모든 트리거된 액션 핸들러를 처리하는 Promise를 반환합니다. [상세](actions.md)
+
+- **`replaceState(state: Object)`**
+
+  저장소의 루트 상태를 바꿉니다. 상태에 대한 상호작용/시점 변경 목적으로 만 사용하십시오.
+
+- **`watch(getter: Function, cb: Function, options?: Object)`**
+
+  getter 함수의 반환 값을 반응적으로 지켜보고 값이 변경되면 콜백을 호출합니다. getter는 저장소의 상태를 유일한 인수로받습니다. Vue의 `vm.$watch` 메소드와 같은 옵션을 취하는 옵션 객체를 받아들입니다.
+
+  감시를 중단하려면 반환된 핸들 함수를 호출하십시오.
+
+- **`subscribe(handler: Function)`**
+
+  저장소 변이를 구독합니다. `handler`는 모든 변이 이후 호출되고 변이 디스크립터와 변이 상태를 전달인자로 받습니다.
+
+  ``` js
+  store.subscribe((mutation, state) => {
+    console.log(mutation.type)
+    console.log(mutation.payload)
+  })
+  ```
+
+  플러그인에서 가장 일반적으로 사용됩니다. [상세](plugins.md)
+
+- **`registerModule(path: string | Array<string>, module: Module)`**
+
+  동적 모듈을 등록합니다. [상세](modules.md#dynamic-module-registration)
+
+- **`unregisterModule(path: string | Array<string>)`**
+
+  동적 모듈을 해제 합니다. [상세](modules.md#dynamic-module-registration)
+
+- **`hotUpdate(newOptions: Object)`**
+
+  새 액션과 변이를 핫 스왑 합니다. [상세](hot-reload.md)
+
+### 컴포넌트 바인딩 헬퍼
+
+- **`mapState(map: Array<string> | Object): Object`**
+
+  Vuex 저장소의 하위 트리를 반환하는 컴포넌트 계산 옵션을 만듭니다. [상세](state.md#the-mapstate-helper)
+
+- **`mapGetters(map: Array<string> | Object): Object`**
+
+  getter의 평가된 값을 반환하는 컴포넌트 계산 옵션을 만듭니다. [상세](getters.md#the-mapgetters-helper)
+
+- **`mapActions(map: Array<string> | Object): Object`**
+
+  액션을 전달하는 컴포넌트 메소드 옵션을 만듭니다. [상세](actions.md#dispatching-actions-in-components)
+
+- **`mapMutations(map: Array<string> | Object): Object`**
+
+  변이를 커밋하는 컴포넌트 메소드 옵션을 만듭니다. [상세](mutations.md#commiting-mutations-in-components)

+ 19 - 0
docs/ko/book.json

@@ -0,0 +1,19 @@
+{
+  "gitbook": "2.x.x",
+  "plugins": ["edit-link", "prism", "-highlight", "github"],
+  "pluginsConfig": {
+    "edit-link": {
+      "base": "https://github.com/vuejs/vuex/tree/dev/docs",
+      "label": "Edit This Page"
+    },
+    "github": {
+      "url": "https://github.com/vuejs/vuex/"
+    }
+  },
+  "links": {
+    "sharing": {
+      "facebook": false,
+      "twitter": false
+    }
+  }
+}

+ 57 - 0
docs/ko/forms.md

@@ -0,0 +1,57 @@
+# 폼 핸들링
+
+strict 모드로 Vuex를 사용하는 경우 Vuex에 포함된 부분에 `v-model`을 사용하는 것은 약간 까다로울 수 있습니다.
+
+``` html
+<input v-model="obj.message">
+```
+
+`obj`가 저장소에서 객체를 반환하는 계산된 속성이라면, 여기에있는 `v-model`은 사용자가 입력 할 때 `obj.message`를 직접 변경하려고 합니다. strict 모드에서는 Vuex 변이 처리기 내부에서 변이가 수행되지 않으므로 오류가 발생합니다.
+
+그것을 다루는 "Vuex 방식"은 `<input>`의 값을 바인딩하고 `input` 또는 `change` 이벤트에 대한 액션을 호출하는 것 입니다.
+
+``` html
+<input :value="message" @input="updateMessage">
+```
+``` js
+// ...
+computed: {
+  ...mapState({
+    message: state => state.obj.message
+  })
+},
+methods: {
+  updateMessage (e) {
+    this.$store.commit('updateMessage', e.target.value)
+  }
+}
+```
+
+변이에 대한 핸들러 입니다.
+
+``` js
+// ...
+mutations: {
+  updateMessage (state, message) {
+    state.obj.message = message
+  }
+}
+```
+
+### 양방향 계산된 속성
+
+틀림없이, 위의 내용은 `v-model` + 지역 상태보다 좀더 장황 해졌고, `v-model`의 유용한 기능 중 일부를 잃어 버렸습니다. 다른 방법은 setter를 사용하여 양방향 계산된 속성을 사용하는 것입니다.
+
+``` js
+// ...
+computed: {
+  message: {
+    get () {
+      return this.$store.state.obj.message
+    },
+    set (value) {
+      this.$store.commit('updateMessage', value)
+    }
+  }
+}
+```

+ 91 - 0
docs/ko/getters.md

@@ -0,0 +1,91 @@
+# Getters
+
+때로는 저장소 상태를 기반하는 상태를 계산해야 할 수도 있습니다.(예: 아이템 리스트를 필터링하고 계산)
+
+``` js
+computed: {
+  doneTodosCount () {
+    return this.$store.state.todos.filter(todo => todo.done).length
+  }
+}
+```
+
+둘 이상의 컴포넌트가 이를 사용 해야하는 경우 함수를 복제하거나 공유된 헬퍼를 추출하여 여러 위치에서 가져와야합니다. 둘 다 이상적이지 않습니다.
+
+Vuex를 사용하면 저장소에서 "getters"를 정의 할 수 있습니다(저장소의 계산된 속성으로 생각됩니다). Getters는 첫 번째 전달인자로 상태를 받습니다.
+
+``` js
+const store = new Vuex.Store({
+  state: {
+    todos: [
+      { id: 1, text: '...', done: true },
+      { id: 2, text: '...', done: false }
+    ]
+  },
+  getters: {
+    doneTodos: state => {
+      return state.todos.filter(todo => todo.done)
+    }
+  }
+})
+```
+
+getters는 `store.getters` 객체에 노출 됩니다.
+
+``` js
+store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
+```
+
+Getters는 두 번째 전달인자로 다른 getter도 받게됩니다.
+
+``` js
+getters: {
+  // ...
+  doneTodosCount: (state, getters) => {
+    return getters.doneTodos.length
+  }
+}
+```
+
+``` js
+store.getters.doneTodosCount // -> 1
+```
+
+이제 모든 컴포넌트에서 쉽게 사용할 수 있습니다.
+
+``` js
+computed: {
+  doneTodosCount () {
+    return this.$store.getters.doneTodosCount
+  }
+}
+```
+
+### `mapGetters` 헬퍼
+
+`mapGetters` 헬퍼는 저장소 getter를 로컬 계산된 속성에 매핑합니다.
+
+``` js
+import { mapGetters } from 'vuex'
+
+export default {
+  // ...
+  computed: {
+    // getter를 객체 전파 연산자로 계산하여 추가합니다.
+    ...mapGetters([
+      'doneTodosCount',
+      'anotherGetter',
+      // ...
+    ])
+  }
+}
+```
+
+getter를 다른 이름으로 매핑하려면 객체를 사용합니다.
+
+``` js
+...mapGetters({
+  // this.doneCount를 store.getters.doneTodosCount에 매핑하십시오.
+  doneCount: 'doneTodosCount'
+})
+```

+ 43 - 0
docs/ko/getting-started.md

@@ -0,0 +1,43 @@
+# 시작하기
+
+모든 Vuex 애플리케이션의 중심에는 **store** 가 있습니다. "저장소"는 기본적으로 애플리케이션 **상태** 를 보유하고있는 컨테이너입니다. Vuex 저장소가 일반 전역 개체와 두 가지 다른 점이 있습니다.
+
+1. Vuex store는 반응형 입니다. Vue 컴포넌트는 상태를 검색할 때 저장소의 상태가 변경되면 효율적으로 대응하고 업데이트합니다.
+2. 저장소의 상태를 직접 변경할 수 없습니다. 저장소의 상태를 변경하는 유일한 방법은 명시적인 **커밋을 이용한 변이** 입니다. 이렇게하면 모든 상태에 대한 추적이 가능한 기록이 남을 수 있으며 툴를 사용하여 앱을 더 잘 이해할 수 있습니다.
+
+### 가장 단순한 저장소
+
+> **참고:** 모든 예제는 ES2015 문법을 사용합니다. 사용하고 있지 않은 경우 [꼭 사용해야 합니다!](https://babeljs.io/docs/learn-es2015/)
+
+Vuex를 [설치](installation.md)한 후 저장소를 만들어 봅시다. 매우 간단합니다. 초기 상태 객체와 일부 변이를 제공하십시오.
+
+``` js
+// 모듈 시스템을 사용하는 경우 Vue.use(Vuex)를 먼저 호출해야합니다.
+
+const store = new Vuex.Store({
+  state: {
+    count: 0
+  },
+  mutations: {
+    increment (state) {
+      state.count++
+    }
+  }
+})
+```
+
+이제 state 객체에 `store.state`로 접근하여 `store.commit` 메소드로 상태 변경을 트리거 할 수 있습니다.
+
+``` js
+store.commit('increment')
+
+console.log(store.state.count) // -> 1
+```
+
+다시 말해, `store.state.count`를 직접 변경하는 대신 변이를 수행하는 이유는 명시적으로 추적을 하기 때문입니다. 이 간단한 규칙에 따라 의도를보다 명확하게 표현할 수 있으므로 코드를 읽을 때 상태 변화를 더 잘 지켜볼 수 있습니다. 또한 모든 변이를 기록하고 상태 스냅샷을 저장하거나 시간 흐름에 따라 디버깅을 할 수 있는 도구를 제공합니다.
+
+컴포넌트 안에서 저장소 상태를 사용하는 것은 단순히 계산된 속성 내에서 상태를 반환하는 것입니다. 변경을 트리거하는 것은 컴포넌트 메소드에서 변경을 커밋하는 것을 의미합니다.
+
+다음은 [가장 기본적인 Vuex 카운터 앱](https://jsfiddle.net/yyx990803/n9jmu5v7/)의 예입니다.
+
+이제, 우리는 각 핵심 개념에 대해 더 자세히 설명 할 것입니다. [State](state.md)부터 시작해 보겠습니다.

+ 44 - 0
docs/ko/hot-reload.md

@@ -0,0 +1,44 @@
+# 핫 리로딩
+
+Vuex는 Webpack의 [핫 모듈 변경 API](https://webpack.github.io/docs/hot-module-replacement.html)를 사용하여 개발 중에 핫 리로드 변이, 모듈, 액션 및 getter를 지원합니다. [browserify-hmr](https://github.com/AgentME/browserify-hmr/) 플러그인으로 Browserify에서 사용할 수도 있습니다.
+
+변이와 모듈의 경우, `store.hotUpdate()` API 메소드를 사용할 필요가 있습니다.
+
+``` js
+// store.js
+import Vue from 'vue'
+import Vuex from 'vuex'
+import mutations from './mutations'
+import moduleA from './modules/a'
+
+Vue.use(Vuex)
+
+const state = { ... }
+
+const store = new Vuex.Store({
+  state,
+  mutations,
+  modules: {
+    a: moduleA
+  }
+})
+
+if (module.hot) {
+  // 액션과 변이를 핫 모듈로 받아 들인다.
+  module.hot.accept(['./mutations', './modules/a'], () => {
+    // 업데이트 된 모듈은 babel 6 모듈 출력으로 인해
+    // .default를 여기에 추가해야합니다.
+    const newMutations = require('./mutations').default
+    const newModuleA = require('./modules/a').default
+    // 새로운 액션과 변이로 바꿉니다.
+    store.hotUpdate({
+      mutations: newMutations,
+      modules: {
+        a: newModuleA
+      }
+    })
+  })
+}
+```
+
+[counter-hot 예제](https://github.com/vuejs/vuex/tree/dev/examples/counter-hot)로 핫 리로드를 확인하십시오.

二進制
docs/ko/images/flow.png


二進制
docs/ko/images/vuex.png


+ 51 - 0
docs/ko/installation.md

@@ -0,0 +1,51 @@
+# 설치
+
+### 직접 다운로드 / CDN
+
+[https://unpkg.com/vuex](https://unpkg.com/vuex)
+
+<!--email_off-->
+[Unpkg.com](https://unpkg.com)은 NPM 기반 CDN 링크를 제공합니다. 위의 링크는 항상 NPM의 최신 릴리스를 가리킵니다. `https://unpkg.com/vuex@2.0.0`과 같은 URL을 통해 특정 버전/태그를 사용할 수도 있습니다.
+<!--/email_off-->
+
+Vue 뒤에 `vuex`를 추가하면 자동으로 설치됩니다:
+
+``` html
+<script src="/path/to/vue.js"></script>
+<script src="/path/to/vuex.js"></script>
+```
+
+### NPM
+
+``` bash
+npm install vuex
+```
+
+### Yarn
+
+``` bash
+yarn add vuex
+```
+
+모듈 시스템과 함께 사용하면 `Vue.use()`를 통해 Vuex를 명시적으로 추가해야 합니다.
+
+``` js
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+```
+
+전역 스크립트 태그를 사용할 때는 이 작업을 할 필요가 없습니다.
+
+### 개발용 빌드
+
+최신 dev 빌드를 사용하고 싶은 경우 직접 GitHub에서 클론하고 `vuex`를 직접 빌드 해야합니다.
+
+
+``` bash
+git clone https://github.com/vuejs/vuex.git node_modules/vuex
+cd node_modules/vuex
+npm install
+npm run build
+```

+ 63 - 0
docs/ko/intro.md

@@ -0,0 +1,63 @@
+# Vuex가 무엇인가요?
+
+Vuex는 Vue.js 애플리케이션에 대한 **상태 관리 패턴 + 라이브러리** 입니다. 애플리케이션의 모든 컴포넌트에 대한 중앙 집중식 저장소 역할을 하며 예측 가능한 방식으로 상태를 변경할 수 있습니다. 또한 Vue의 공식 [devtools 확장 프로그램](https://github.com/vuejs/vue-devtools)과 통합되어 설정 시간이 필요 없는 디버깅 및 상 태 스냅 샷 내보내기/가져오기와 같은 고급 기능을 제공합니다.
+
+### "상태 관리 패턴"이란 무엇인가요?
+
+간단한 Vue 카운터 앱부터 시작 해보겠습니다.
+
+``` js
+new Vue({
+  // 상태
+  data () {
+    return {
+      count: 0
+    }
+  },
+  // 뷰
+  template: `
+    <div>{{ count }}</div>
+  `,
+  // 액션
+  methods: {
+    increment () {
+      this.count++
+    }
+  }
+})
+```
+
+다음과 같은 기능을 가진 앱입니다.
+
+- **상태** 는 앱을 작동하는 원본 소스 입니다.
+- **뷰** 는 **상태의** 선언적 매핑입니다.
+- **액션** 은 **뷰** 에서 사용자 입력에 대해 반응적으로 상태를 바꾸는 방법입니다.
+
+이것은 "단방향 데이터 흐름" 개념의 매우 단순한 도표입니다.
+
+<p style="text-align: center; margin: 2em">
+  <img style="max-width:450px;" src="./images/flow.png">
+</p>
+
+그러나 **공통의 상태를 공유하는 여러 컴포넌트** 가 있는 경우 단순함이 빠르게 저하됩니다.
+
+- 여러 뷰는 같은 상태에 의존합니다.
+- 서로 다른 뷰의 작업은 동일한 상태를 반영해야 할 수 있습니다.
+
+첫번째 문제의 경우, 지나치게 중첩된 컴포넌트는 통과하는 prop는 장황할 수 있으며 형제 컴포넌트에서는 작동하지 않습니다. 두번째 문제의 경우 직접 부모/자식 인스턴스를 참조하거나 이벤트를 통해 상태의 여러 복사본을 변경 및 동기화 하려는 등의 해결 방법을 사용해야 합니다. 이러한 패턴은 모두 부서지기 쉽고 유지보수가 불가능한 코드로 빠르게 변경됩니다.
+
+그렇다면 컴포넌트에서 공유된 상태를 추출하고 이를 전역 싱글톤으로 관리해야 합니다. 이를 통해 우리의 컴포넌트 트리는 커다란 "뷰"가 되며 모든 컴포넌트는 트리에 상관없이 상태에 액세스하거나 동작을 트리거 할 수 있습니다!
+
+또한 상태 관리 및 특정 규칙 적용과 관련된 개념을 정의하고 분리함으로써 코드의 구조와 유지 관리 기능을 향상시킵니다.
+
+이는 [Flux](https://facebook.github.io/flux/docs/overview.html), [Redux](http://redux.js.org/), [The Elm Architecture](https://guide.elm-lang.org/architecture/)에서 영감을 받은 Vuex의 기본 아이디어 입니다. 다른 패턴과 달리 Vuex는 Vue.js가 효율적인 업데이트를 위해 세분화된 반응 시스템을 활용하도록 특별히 고안된 라이브러리입니다.
+
+![vuex](./images/vuex.png)
+
+### 언제 사용해야 하나요?
+
+Vuex는 공유된 상태 관리를 처리하는 데 유용하지만, 개념에 대한 이해와 시작하는 비용도 함께 듭니다. 그것은 단기간과 장기간 생산성 간의 기회비용이 있습니다.
+
+대규모 SPA를 구축하지 않고 Vuex로 바로 뛰어 들었다면, 시간이 오래 걸리고 힘든일일 것입니다. 이것은 일반 적인 일입니다. 앱이 단순하다면 Vuex없이는 괜찮을 것입니다. 간단한 [글로벌 이벤트 버스](http://vuejs.org/guide/components.html#Non-Parent-Child-Communication)만 있으면됩니다. 그러나 중대형 규모의 SPA를 구축하는 경우 Vue컴포넌트 외부의 상태를 보다 잘 처리할 수 있는 방법을 생각하게 될 가능성이 있으며 Vuex는 자연스럽게 선택할 수 있는 단계가 될 것입니다. Redux의 저자인 Dan Abramov의 좋은 인용이 있습니다.
+
+> Flux 라이브러리는 안경과 같습니다. 필요할 때 알아볼 수 있습니다.

+ 138 - 0
docs/ko/modules.md

@@ -0,0 +1,138 @@
+# 모듈
+
+단일 상태 트리를 사용하기 때문에 애플리케이션의 모든 상태가 하나의 큰 객체 안에 포함됩니다. 그러나 규모가 커짐에 따라 저장소는 매우 비대해질 수 있습니다.
+
+이를 위해 Vuex는 저장소를 **모듈** 로 나눌 수 있습니다. 각 모듈은 자체 상태, 변이, 액션, 게터 및 심지어 중첩된 모듈을 포함 할 수 있습니다.
+
+``` js
+const moduleA = {
+  state: { ... },
+  mutations: { ... },
+  actions: { ... },
+  getters: { ... }
+}
+
+const moduleB = {
+  state: { ... },
+  mutations: { ... },
+  actions: { ... }
+}
+
+const store = new Vuex.Store({
+  modules: {
+    a: moduleA,
+    b: moduleB
+  }
+})
+
+store.state.a // -> moduleA'의 상태
+store.state.b // -> moduleB'의 상태
+```
+
+### 지역 상태 모듈
+
+모듈의 변이와 getter 내부에서 첫 번째 전달인자는 **모듈의 지역 상태** 가됩니다.
+
+``` js
+const moduleA = {
+  state: { count: 0 },
+  mutations: {
+    increment: (state) {
+      // state는 지역 모듈 상태 입니다
+      state.count++
+    }
+  },
+
+  getters: {
+    doubleCount (state) {
+      return state.count * 2
+    }
+  }
+}
+```
+
+유사하게 모듈 내부에서 `context.state`는 지역 상태를 노출시킬 것이고 루트 상태는 `context.rootState`로 노출 될 것입니다.
+
+``` js
+const moduleA = {
+  // ...
+  actions: {
+    incrementIfOdd ({ state, commit }) {
+      if (state.count % 2 === 1) {
+        commit('increment')
+      }
+    }
+  }
+}
+```
+
+또한, 모듈 getters 내부, 루트 상태는 그들의 세 번째 전달인자로 노출됩니다.
+
+``` js
+const moduleA = {
+  // ...
+  getters: {
+    sumWithRootCount (state, getters, rootState) {
+      return state.count + rootState.count
+    }
+  }
+}
+```
+
+### 네임스페이스
+
+모듈 내의 액션, 변이 및 getter는 여전히 **전역 네임 스페이스** 아래에 등록됩니다. 여러 모듈이 동일한 변이/액션 유형에 반응 할 수 있습니다. 이름 앞에 접두사 또는 접미사를 붙이면 이름 충돌을 피하기 위해 모듈 자신의 네임스페이스를 직접 지정할 수 있습니다. 그리고 알 수 없는 환경에서 사용될 재사용 가능한 Vuex 모듈을 작성하는 경우라면 반드시 사용해야 합니다. 예를 들어,`todos` 모듈을 만들고 싶은 경우
+
+``` js
+// types.js
+
+// getter, 액션, 변이의 이름을 상수로 정의하고
+// 모듈 이름 `todos` 접두어를 붙입니다
+export const DONE_COUNT = 'todos/DONE_COUNT'
+export const FETCH_ALL = 'todos/FETCH_ALL'
+export const TOGGLE_DONE = 'todos/TOGGLE_DONE'
+```
+
+``` js
+// modules/todos.js
+import * as types from '../types'
+
+// 접두어로 된 이름을 사용하여 getter, 액션 및 변이 정의
+const todosModule = {
+  state: { todos: [] },
+
+  getters: {
+    [types.DONE_COUNT] (state) {
+      // ...
+    }
+  },
+
+  actions: {
+    [types.FETCH_ALL] (context, payload) {
+      // ...
+    }
+  },
+
+  mutations: {
+    [types.TOGGLE_DONE] (state, payload) {
+      // ...
+    }
+  }
+}
+```
+
+### 동적 모듈 등록
+
+`store.registerModule` 메소드로 저장소가 생성 된 **후에** 모듈을 등록 할 수 있습니다.
+
+``` js
+store.registerModule('myModule', {
+  // ...
+})
+```
+
+모듈의 상태는`store.state.myModule`으로 노출 됩니다.
+
+동적 모듈 등록을 사용하면 다른 Vue 플러그인도 애플리케이션의 저장소에 모듈을 연결하여 상태 관리에 Vuex를 활용할 수 있습니다. 예를 들어 [`vuex-router-sync`](https://github.com/vuejs/vuex-router-sync) 라이브러리는 동적으로 연결된 모듈에서 애플리케이션의 라우트 상태를 관리하여 vue-router와 vuex를 통합합니다.
+
+`store.unregisterModule(moduleName)`을 사용하여 동적으로 등록 된 모듈을 제거할 수도 있습니다. 이 방법으로는 정적 모듈(저장소 생성시 선언 됨)을 제거 할 수 없습니다.

+ 185 - 0
docs/ko/mutations.md

@@ -0,0 +1,185 @@
+# 변이
+
+Vuex 저장소에서 실제로 상태를 변경하는 유일한 방법은 변이하는 것입니다. Vuex 변이는 이벤트와 매우 유사합니다. 각 변이에는 **타입** 문자열 **핸들러** 가 있습니다. 핸들러 함수는 실제 상태 수정을 하는 곳이며, 첫 번째 전달인자로 상태를받습니다.
+
+``` js
+const store = new Vuex.Store({
+  state: {
+    count: 1
+  },
+  mutations: {
+    increment (state) {
+      // 상태 변이
+      state.count++
+    }
+  }
+})
+```
+
+변이 핸들러를 직접 호출 할 수는 없습니다. 이 옵션은 이벤트 등록과 비슷합니다. "타입이 `increment`인 변이가 발생하면이 핸들러를 호출합니다." 변이 핸들러를 호출하려면 해당 타입과 함께 **store.commit** 을 호출해야합니다.
+
+``` js
+store.commit('increment')
+```
+
+### 페이로드를 가진 커밋
+
+변이에 대해 **payload** 라고하는 `store.commit`에 추가 전달인자를 사용 할 수 있습니다.
+
+``` js
+// ...
+mutations: {
+  increment (state, n) {
+    state.count += n
+  }
+}
+```
+``` js
+store.commit('increment', 10)
+```
+
+대부분의 경우 페이로드는 여러 필드를 포함할 수 있는 객체여야하며 기록 된 변이는 더 이해하기 쉽습니다.
+
+``` js
+// ...
+mutations: {
+  increment (state, payload) {
+    state.count += payload.amount
+  }
+}
+```
+``` js
+store.commit('increment', {
+  amount: 10
+})
+```
+
+### 객체 스타일 커밋
+
+변이를 커밋하는 또 다른 방법은 `type` 속성을 가진 객체를 직접 사용하는 것입니다.
+
+``` js
+store.commit({
+  type: 'increment',
+  amount: 10
+})
+```
+
+객체 스타일 커밋을 사용할 때 전체 객체는 변이 핸들러에 페이로드로 전달되므로 핸들러는 동일하게 유지됩니다.
+
+``` js
+mutations: {
+  increment (state, payload) {
+    state.count += payload.amount
+  }
+}
+```
+
+### 조용한 커밋
+
+> 참고: 이것은 devtools에서 변이 필터링을 구현하면 더 이상 사용되지 않을 예정입니다.
+
+기본적으로 커밋 된 모든 변이는 플러그인(예: devtools)에 전송됩니다. 그러나 일부 시나리오에서는 플러그인이 모든 상태 변경을 기록하는 것을 원하지 않을 수도 있습니다. 단기간에 저장소에 대한 여러 커밋나 폴링 된 것이 항상 추적될 필요는 없습니다. 이 경우 세 번째 인수를 `store.commit`에 전달하여 플러그인에서 특정 변이를 "조용하게" 할 수 있습니다.
+
+``` js
+store.commit('increment', {
+  amount: 1
+}, { silent: true })
+
+// 객체 스타일 커밋
+store.commit({
+  type: 'increment',
+  amount: 1
+}, { silent: true })
+```
+
+### Vue의 반응성 규칙을 따르는 변이
+
+Vuex 저장소의 상태는 Vue에 의해 반응하므로, 상태를 변경하면 상태를 관찰하는 Vue 컴포넌트가 자동으로 업데이트됩니다. 이것은 또한 Vuex 변이가 일반 Vue로 작업 할 때 동일한 반응성에 대한 경고를 받을 수 있음을 의미합니다.
+
+1. 원하는 모든 필드에 앞서 저장소를 초기화하는 것이 좋습니다.
+
+2. 객체에 새 속성을 추가할 때 다음 중 하나를 수행해야합니다.
+
+  - `Vue.set(obj, 'newProp', 123)`을 사용하거나,
+
+  - 객체를 새로운 것으로 교체하십시오. 예를 들어, 3 단계 [객체 전파 문법](https://github.com/sebmarkbage/ecmascript-rest-spread)을 사용하면 다음과 같이 작성할 수 있습니다.
+
+    ``` js
+    state.obj = { ...state.obj, newProp: 123 }
+    ```
+
+### 변이 타입에 상수 사용
+
+다양한 Flux 구현에서 변이 유형에 상수를 사용하는 것은 일반인 패턴입니다. 이를 통해 코드는 linter와 같은 툴링을 활용할 수 있으며 모든 상수를 단일 파일에 저장하면 공동 작업자가 전체 애플리케이션에서 어떤 변이가 가능한지 한눈에 파악할 수 있습니다.
+
+``` js
+// mutation-types.js
+export const SOME_MUTATION = 'SOME_MUTATION'
+```
+
+``` js
+// store.js
+import Vuex from 'vuex'
+import { SOME_MUTATION } from './mutation-types'
+
+const store = new Vuex.Store({
+  state: { ... },
+  mutations: {
+    // ES2015에서 계산 된 프로퍼티 이름 기능을 사용하여
+    // 상수를 함수 이름으로 사용할 수 있습니다
+    [SOME_MUTATION] (state) {
+      // 변이 상태
+    }
+  }
+})
+```
+
+상수를 사용할지 여부는 대부분 환경 설정입니다. 개발자가 많은 대규모 프로젝트에서 유용할 수 있지만, 이는 완전히 선택 사항입니다.
+
+### 변이는 무조건 동기적이어야 합니다.
+
+기억 해야할 한 가지 중요한 규칙은 **변이 핸들러 함수는 동기적** 이어야 한다는 것입니다. 왜 그럴까요? 다음 예제를 확인해보십시오.
+
+``` js
+mutations: {
+  someMutation (state) {
+    api.callAsyncMethod(() => {
+      state.count++
+    })
+  }
+}
+```
+
+이제 우리가 앱을 디버깅하고 devtool의 돌연변이 로그를 보고 있다고 상상해보십시오. 기록 된 모든 변이에 대해 devtool은 상태의 "이전" 및 "이후" 스냅 샷을 캡처 해야 합니다. 그러나 위의 예제 변이 내의 비동기 콜백은 불가능합니다. 변이가 커밋 되었을 때 콜백은 아직 호출되지 않으며, 콜백이 실제로 호출 될 시기를 devtool이 알 수 있는 방법이 없습니다. 콜백에서 수행 된 모든 상태 변이는 본질적으로 추적 할 수 없습니다!
+
+### 컴포넌트 안에서 변이 커밋하기
+
+`this.$store.commit('xxx')`를 사용하여 컴포넌트에서 변이를 수행하거나 컴포넌트 메소드를 `store.commit` 호출에 매핑하는 `mapMutations` 헬퍼를 사용할 수 있습니다 (루트 `store` 주입 필요)
+
+``` js
+import { mapMutations } from 'vuex'
+
+export default {
+  // ...
+  methods: {
+    ...mapMutations([
+      'increment' // this.increment()를 this.$store.commit('increment')에 매핑합니다.
+    ]),
+    ...mapMutations({
+      add: 'increment' // this.add()를 this.$store.commit('increment')에 매핑합니다.
+    })
+  }
+}
+```
+
+### 액션에서 사용
+
+비동기성이 상태의 변이와 결합하면 프로그램을 파악하기가 매우 어려워 질 수 있습니다. 예를 들어 상태를 변경하는 두 가지 비동기 콜백 메소드를 호출할 때 호출되는 시점과 먼저 호출 된 콜백을 어떻게 알 수 있습니까? 이것이 우리가 두 개념을 분리하려는 이유입니다. Vuex에서 **변이는 동기적으로 트랜잭션합니다.**
+
+``` js
+store.commit('increment')
+// "increment" 변이가 일으킬 수 있는 모든 상태 변화는 이 순간에 이루어져야합니다.
+```
+
+비동기 작업을 처리하기 위한 [액션](actions.md)를 소개합시다.

+ 121 - 0
docs/ko/plugins.md

@@ -0,0 +1,121 @@
+# 플러그인
+
+Vuex 저장소는 각 변이에 대한 훅을 노출하는 `plugins` 옵션을 허용합니다. Vuex 플러그인은 저장소를 유일한 전달인자로 받는 함수입니다.
+
+``` js
+const myPlugin = store => {
+  // 저장소가 초기화 될 때 불립니다.
+  store.subscribe((mutation, state) => {
+    // 매 변이시마다 불립니다.
+    // 변이는 { type, payload } 포맷으로 제공됩니다.
+  })
+}
+```
+
+그리고 다음과 같이 사용할 수 있습니다.
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  plugins: [myPlugin]
+})
+```
+
+### 플러그인 내부에서 변이 커밋하기
+
+플러그인은 상태를 직접 변이할 수 없습니다. 컴포넌트와 마찬가지로 변이를 커밋하여 변경을 트리거 할 수 있습니다.
+
+변이을 커밋함으로써 플러그인을 사용하여 데이터 소스를 저장소에 동기화 할 수 있습니다. 예를 들어, websocket 데이터 소스를 저장소에 동기화하려면 (이는 사실 인위적인 예제입니다. 실제로 `createPlugin` 함수는 더 복잡한 작업을 위해 몇 가지 추가 옵션을 필요로 할 수 있습니다)
+
+``` js
+export default function createWebSocketPlugin (socket) {
+  return store => {
+    socket.on('data', data => {
+      store.commit('receiveData', data)
+    })
+    store.subscribe(mutation => {
+      if (mutation.type === 'UPDATE_DATA') {
+        socket.emit('update', mutation.payload)
+      }
+    })
+  }
+}
+```
+
+``` js
+const plugin = createWebSocketPlugin(socket)
+
+const store = new Vuex.Store({
+  state,
+  mutations,
+  plugins: [plugin]
+})
+```
+
+### 상태 스냅샷 가져오기
+
+때로는 플러그인이 상태의 "스냅샷"을 얻고자 할 수 있으며, 또한 변이 이후 상태와 변이 이전 상태를 비교할 수 있습니다. 이를 달성하기 위해서는 상태 객체에 대한 깊은 복사를 수행해야합니다 :
+
+``` js
+const myPluginWithSnapshot = store => {
+  let prevState = _.cloneDeep(store.state)
+  store.subscribe((mutation, state) => {
+    let nextState = _.cloneDeep(state)
+
+    // prevState와 nextState를 비교하십시오.
+
+    // 다음 변이를 위한 상태 저장
+    prevState = nextState
+  })
+}
+```
+
+**상태 스냅 샷을 사용하는 플러그인은 개발 중에 만 사용해야합니다.** Webpack 또는 Browserify를 사용하는 경우 빌드 도구가 이를 처리 할 수 있습니다.
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  plugins: process.env.NODE_ENV !== 'production'
+    ? [myPluginWithSnapshot]
+    : []
+})
+```
+
+플러그인은 기본적으로 사용됩니다. 배포를 위해서는 Webpack의 [DefinePlugin](https://webpack.github.io/docs/list-of-plugins.html#defineplugin) 또는 [envify](https://github.com/hughsk/envify)가 필요합니다. Browserify가 `process.env.NODE_ENV !== 'production'`의 값을 최종 빌드를 위해 `false`로 변환합니다.
+
+
+### 내장 로거 플러그인
+
+> [vue-devtools](https://github.com/vuejs/vue-devtools)를 사용하고 있으면 필요 없을 수 있습니다.
+
+Vuex에는 일반적인 디버깅을 위한 로거 플러그인이 함께 제공됩니다.
+
+``` js
+import createLogger from 'vuex/dist/logger'
+
+const store = new Vuex.Store({
+  plugins: [createLogger()]
+})
+```
+
+`createLogger` 함수는 몇 가지 옵션을 가질 수 있습니다.
+
+``` js
+const logger = createLogger({
+  collapsed: false, // 로그를 가지는 변이 자동 확장
+  transformer (state) {
+    // 로깅하기전 상태를 변이 하십시오.
+    // 예를 들어 특정 하위 트리만 반환합니다.
+    return state.subTree
+  },
+  mutationTransformer (mutation) {
+    // 변이는 { type, payload }의 포맷으로 기록됩니다.
+    // 원하는 포맷으로 변경할 수 있습니다.
+    return mutation.type
+  }
+})
+```
+
+로거 파일은`<script>`태그를 통해 직접 포함될 수 있으며 `createVuexLogger` 함수를 전역적으로 노출합니다.
+
+로거 플러그인은 상태 스냅샷을 사용하므로 개발용으로만 사용하십시오.

+ 109 - 0
docs/ko/state.md

@@ -0,0 +1,109 @@
+# 상태
+
+### 단일 상태 트리
+
+Vuex는 **단일 상태 트리** 를 사용합니다. 즉, 이 단일 객체는 모든 애플리케이션 수준의 상태를 포함하며 "원본 소스" 역할을 합니다. 이는 각 애플리케이션마다 하나의 저장소만 갖게 된다는 것을 의미합니다. 단일 상태 트리를 사용하면 특정 상태를 쉽게 찾을 수 있으므로 디버깅을 위해 현재 앱 상태의 스냅 샷을 쉽게 가져올 수 있습니다.
+
+단일 상태 트리는 모듈성과 충돌하지 않습니다. 나중에 상태와 변이를 하위 모듈로 분할하는 방법에 대해 설명합니다.
+
+### Vuex 상태를 Vue 컴포넌트에서 가져오기
+
+그러면 Vue 컴포넌트에서 저장소 내부의 상태를 어떻게 표시하나요? Vuex 저장소는 반응적이기 때문에 저장소에서 상태를 "검색"하는 가장 간단한 방법은 [계산된 속성](http://vuejs.org/guide/computed.html)내에서 일부 저장소 상태를 가져오는 것입니다.
+
+``` js
+// Counter 컴포넌트를 만듭니다
+const Counter = {
+  template: `<div>{{ count }}</div>`,
+  computed: {
+    count () {
+      return store.state.count
+    }
+  }
+}
+```
+
+`store.state.count`가 변경되면 계산된 속성이 다시 변경되고 관련 DOM 업데이트가 트리거됩니다.
+
+그러나 이 패턴은 컴포넌트가 전역 저장소 단독 항목에 의존하게합니다. 모듈 시스템을 사용할 때는 저장소 상태를 사용하는 모든 컴포넌트에서 저장소를 가져와야하며 컴포넌트를 테스트 할 때는 가짜데이터가 필요합니다.
+
+Vuex는 `store` 옵션(`Vue.use(Vuex)`에 의해 가능)으로 루트 컴포넌트의 모든 자식 컴포넌트에 저장소를 "주입"하는 메커니즘을 제공합니다.
+
+``` js
+const app = new Vue({
+  el: '#app',
+  // "store" 옵션을 사용하여 저장소를 제공하십시오.
+  // 그러면 모든 하위 컴포넌트에 저장소 인스턴스가 삽입됩니다.
+  store,
+  components: { Counter },
+  template: `
+    <div class="app">
+      <counter></counter>
+    </div>
+  `
+})
+```
+
+루트 인스턴스에 `store` 옵션을 제공함으로써 저장소는 루트의 모든 하위 컴포넌트에 주입되고 `this.$store`로 사용할 수 있습니다. `Counter` 구현을 수정해야 합니다.
+
+``` js
+const Counter = {
+  template: `<div>{{ count }}</div>`,
+  computed: {
+    count () {
+      return this.$store.state.count
+    }
+  }
+}
+```
+
+### `mapState` 헬퍼
+
+컴포넌트가 여러 저장소 상태 속성이나 getter를 사용해야하는 경우 계산된 속성을 모두 선언하면 반복적이고 장황해집니다. 이를 처리하기 위해 우리는 계산된 getter 함수를 생성하는 `mapState` 헬퍼를 사용하여 키 입력을 줄일 수 있습니다.
+
+``` js
+// 독립 실행 형 빌드에서 헬퍼가 Vuex.mapState로 노출됩니다.
+import { mapState } from 'vuex'
+
+export default {
+  // ...
+  computed: mapState({
+    // 화살표 함수는 코드를 매우 간결하게 만들어 줍니다!
+    count: state => state.count,
+
+    // 문자열 값 'count'를 전달하는 것은 `state => state.count`와 같습니다.
+    countAlias: 'count',
+
+    // `this`를 사용하여 로컬 상태에 액세스하려면 일반적인 함수를 사용해야합니다
+    countPlusLocalState (state) {
+      return state.count + this.localCount
+    }
+  })
+}
+```
+
+또한 매핑 된 계산된 속성의 이름이 상태 하위 트리 이름과 같을 때 문자열 배열을 `mapState`에 전달할 수 있습니다.
+
+``` js
+computed: mapState([
+  // this.count를 store.state.count에 매핑 합니다.
+  'count'
+])
+```
+
+### 객체 전파 연산자
+
+`mapState`는 객체를 반환합니다. 다른 로컬 영역의 계산된 속성과 함께 사용하려면 어떻게 해야 하나요? 일반적으로, 최종 객체를 `computed`에 전달할 수 있도록 여러 객체를 하나로 병합하는 유틸리티를 사용해야합니다. 그러나 (3 단계 ECMAScript 스펙) [객체 확산 연산자](https://github.com/sebmarkbage/ecmascript-rest-spread)을 사용하면 문법을 매우 단순화 할 수 있습니다.
+
+``` js
+computed: {
+  localComputed () { /* ... */ },
+  // 이것을 객체 전파 연산자를 사용하여 외부 객체에 추가 하십시오.
+  ...mapState({
+    // ...
+  })
+}
+```
+
+### 컴포넌트에는 여전히 로컬 상태가 있을 수 있습니다.
+
+Vuex를 사용한다고해서 Vuex에 **모든** 상태를 넣어야하는 것은 아닙니다. Vuex에 더 많은 상태를 넣으면 상태 변이가 더 명확하고 디버그 가능하지만, 때로는 코드를 보다 장황하고 간접적으로 만들 수 있습니다. 상태 조각이 단일 컴포넌트에 엄격하게 속한 경우 로컬 상태로 남겨 둘 수 있습니다. 기회비용을 판단하고 앱의 개발 요구에 맞는 결정을 내려야 합니다.

+ 25 - 0
docs/ko/strict.md

@@ -0,0 +1,25 @@
+# Strict 모드
+
+strict 모드를 사용하기 위해, `strict: true`를 Vuex 저장소를 만들 때 추가하면 됩니다.
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  strict: true
+})
+```
+
+엄격 모드에서는 Vuex 상태가 변이 핸들러 외부에서 변이 될 때 마다 오류가 발생합니다. 이렇게하면 디버깅 도구로 모든 상태 변이를 명시적으로 추적 할 수 있습니다.
+
+### 개발 vs. 배포
+
+**배포시 strict 모드를 켜지 마십시오!**  Strict 모드는 부적절한 변이를 감지하기 위해 상태 트리를 자세히 관찰합니다. 성능 이슈를 피하기 위해 배포 환경에서 이를 해제 하십시오.
+
+플러그인과 마찬가지로 빌드 도구가 다음을 처리하도록 할 수 있습니다.
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  strict: process.env.NODE_ENV !== 'production'
+})
+```

+ 33 - 0
docs/ko/structure.md

@@ -0,0 +1,33 @@
+# 애플리케이션 구조
+
+실제로 Vuex는 코드 구조를 제한하지는 않습니다. 이보다 아래에 있는 상위 수준 원칙을 강요합니다.
+
+1. 애플리케이션 레벨의 상태는 중앙 집중된 저장소 입니다.
+
+2. 상태를 변경시키는 유일한 방법은 동기 트랜잭션인 **변이** 를 커밋하는 것입니다.
+
+3. 비동기식 로직은 캡슐화되어야하며 **액션** 으로 구성 됩니다.
+
+
+이 규칙을 따른다면 프로젝트를 구조화하는 것은 사용자에게 달려 있습니다. 저장소 파일이 너무 커지면 액션, 돌연변이 및 getter를 개별 파일로 분할하기만 하면됩니다.
+
+중요한 앱의 경우 모듈을 활용해야 할 가능성이 높습니다. 다음은 프로젝트 구조의 예입니다.
+
+``` bash
+├── index.html
+├── main.js
+├── api
+│   └── ... # API 요청을 위한 추상화를 포함합니다.
+├── components
+│   ├── App.vue
+│   └── ...
+└── store
+    ├── index.js          # 모듈을 조합하고 저장소를 내보내는 곳 입니다.
+    ├── actions.js        # 루트 액션
+    ├── mutations.js      # 루트 변이
+    └── modules
+        ├── cart.js       # cart 모듈
+        └── products.js   # products 모듈
+```
+
+참고 사항으로, [장바구니 예](https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart)를 확인하십시오.

+ 216 - 0
docs/ko/testing.md

@@ -0,0 +1,216 @@
+# 테스팅
+
+Vuex에서 단위 테스트를 하고자 하는 주요 부분은 변이와 액션입니다.
+
+### 변이 테스팅
+
+변이는 테스트하기 매우 간단합니다. 왜냐하면 변이는 전달인자에 완전히 의존하는 함수이기 때문입니다. 한 가지 트릭은 ES2015 모듈을 사용하고 `store.js` 파일에 변이를 넣는다면 기본 내보내기와 함께 변이를 명명된 내보내기로 내보낼 수 있다는 것입니다.
+
+``` js
+const state = { ... }
+
+// 변이를 이름을 가지는 내보내기를 이용하여 내보냅니다.
+export const mutations = { ... }
+
+export default new Vuex.Store({
+  state,
+  mutations
+})
+```
+
+Mocha + Chai를 사용하여 변이를 테스팅 하는 예(원하는 프레임워크/assertion 라이브러리를 사용할 수 있습니다.)
+
+``` js
+// mutations.js
+export const mutations = {
+  increment: state => state.count++
+}
+```
+
+``` js
+// mutations.spec.js
+import { expect } from 'chai'
+import { mutations } from './store'
+
+// 변이 가져오기
+const { increment } = mutations
+
+describe('mutations', () => {
+  it('INCREMENT', () => {
+    // mock 상태
+    const state = { count: 0 }
+    // 변이 적용
+    increment(state)
+    // 결과 확인
+    expect(state.count).to.equal(1)
+  })
+})
+```
+
+### 액션 테스팅
+
+액션은 외부 API를 호출 할 수 있기 때문에 좀 더 까다로울 수 있습니다. 액션을 테스트 할 때 우리는 일반적으로 조작을 어느 정도 해야합니다. 예를 들어 API 호출을 서비스로 추상화하고 테스트 내에서 해당 서비스를 조작 할 수 있습니다. 의존성을 쉽게 모방하기 위해 Webpack과 [inject-loader](https://github.com/plasticine/inject-loader)를 사용하여 테스트 파일을 묶을 수 있습니다.
+
+비동기 액션 테스트 예제:
+
+``` js
+// actions.js
+import shop from '../api/shop'
+
+export const getAllProducts = ({ commit }) => {
+  commit('REQUEST_PRODUCTS')
+  shop.getProducts(products => {
+    commit('RECEIVE_PRODUCTS', products)
+  })
+}
+```
+
+``` js
+// actions.spec.js
+
+// 인라인 로더에는 require 구문을 사용하십시오.
+// inject-loader를 사용하면 조작된 의존성을
+// 주입 할 수있는 모듈 팩토리가 반환됩니다.
+import { expect } from 'chai'
+const actionsInjector = require('inject!./actions')
+
+// 조작된 모의 응답과 함께 모듈 생성
+const actions = actionsInjector({
+  '../api/shop': {
+    getProducts (cb) {
+      setTimeout(() => {
+        cb([ /* 모의 응답 */ ])
+      }, 100)
+    }
+  }
+})
+
+// 예상되는 변이와 함께 테스팅 액션을 도와주는 헬퍼
+const testAction = (action, payload, state, expectedMutations, done) => {
+  let count = 0
+
+  // 모의 커밋
+  const commit = (type, payload) => {
+    const mutation = expectedMutations[count]
+    expect(mutation.type).to.equal(type)
+    if (payload) {
+      expect(mutation.payload).to.deep.equal(payload)
+    }
+    count++
+    if (count >= expectedMutations.length) {
+      done()
+    }
+  }
+
+  // 모의 저장소와 전달인자로 액션을 부릅니다.
+  action({ commit, state }, payload)
+
+  // 디스패치된 변이가 없는지 확인
+  if (expectedMutations.length === 0) {
+    expect(count).to.equal(0)
+    done()
+  }
+}
+
+describe('actions', () => {
+  it('getAllProducts', done => {
+    testAction(actions.getAllProducts, null, {}, [
+      { type: 'REQUEST_PRODUCTS' },
+      { type: 'RECEIVE_PRODUCTS', payload: { /* 모의 응답 */ } }
+    ], done)
+  })
+})
+```
+
+### Getters 테스팅
+
+Getter에 복잡한 연산이 있는 경우 테스트하는 것이 좋습니다. Getter는 변이와 같은 이유로 테스트하는 것이 매우 간단합니다.
+
+getter 테스팅 예제:
+
+``` js
+// getters.js
+export const getters = {
+  filteredProducts (state, { filterCategory }) {
+    return state.products.filter(product => {
+      return product.category === filterCategory
+    })
+  }
+}
+```
+
+``` js
+// getters.spec.js
+import { expect } from 'chai'
+import { getters } from './getters'
+
+describe('getters', () => {
+  it('filteredProducts', () => {
+    // mock state
+    const state = {
+      products: [
+        { id: 1, title: 'Apple', category: 'fruit' },
+        { id: 2, title: 'Orange', category: 'fruit' },
+        { id: 3, title: 'Carrot', category: 'vegetable' }
+      ]
+    }
+    // 모의 getter
+    const filterCategory = 'fruit'
+
+    // getter로 부터 결과를 받습니다
+    const result = getters.filteredProducts(state, { filterCategory })
+
+    // 결과 테스트
+    expect(result).to.deep.equal([
+      { id: 1, title: 'Apple', category: 'fruit' },
+      { id: 2, title: 'Orange', category: 'fruit' }
+    ])
+  })
+})
+```
+
+### 테스트 실행
+
+변이와 액션이 제대로 작성되면 적절한 모의 조작을 한 후 브라우저 API에 직접적인 의존성이 없어야합니다. 따라서 Webpack을 사용하여 테스트를 번들로 묶어 Node를 이용해 직접 실행할 수 있습니다. 또는, `mocha-loader` 나 Karma + `karma-webpack`을 사용하여 실제 브라우저에서 테스트를 실행할 수 있습니다.
+
+#### Node를 이용한 실행
+
+다음과 같이 webpack 설정을 하십시오 ([`.babelrc`](https://babeljs.io/docs/usage/babelrc/)도 함께 필요 합니다.)
+
+``` js
+// webpack.config.js
+module.exports = {
+  entry: './test.js',
+  output: {
+    path: __dirname,
+    filename: 'test-bundle.js'
+  },
+  module: {
+    loaders: [
+      {
+        test: /\.js$/,
+        loader: 'babel',
+        exclude: /node_modules/
+      }
+    ]
+  }
+}
+```
+
+이제,
+
+``` bash
+webpack
+mocha test-bundle.js
+```
+
+#### 브라우저에서 테스팅
+
+1. `mocha-loader`를 설치하세요.
+2. Webpack 설정에서 `entry`를 `'mocha!babel!./test.js'`로 변경하세요.
+3. 설정을 이용하여 `webpack-dev-server`를 실행하세요.
+4. `localhost:8080/webpack-dev-server/test-bundle`로 가세요.
+
+#### 브라우저와 Karma + karma-webpack을 이용한 테스팅
+
+[vue-loader 문서](http://vue-loader.vuejs.org/en/workflow/testing.html)를 확인하세요.