Parcourir la source

Add Portuguese Translation

Finalizando primeira versão da tradução. Falta uma revisão/melhorias nos exemplos

Update docs/pt/SUMMARY.md

Update docs/pt/intro.md

Update docs/pt/getting-started.md

Update docs/pt/getting-started.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/state.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/mutations.md

Update docs/pt/actions.md

Update docs/pt/actions.md

Update docs/pt/actions.md

Update docs/pt/actions.md

Update docs/pt/actions.md

Update docs/pt/structure.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/middlewares.md

Update docs/pt/strict.md

Update docs/pt/strict.md

Update docs/pt/strict.md

Update docs/pt/strict.md

Update docs/pt/strict.md

Update docs/pt/strict.md

Update docs/pt/strict.md

Update docs/pt/strict.md

Update docs/pt/forms.md

Update docs/pt/forms.md

Update docs/pt/forms.md

Update docs/pt/forms.md

Update docs/pt/testing.md

Update docs/pt/testing.md

Update docs/pt/testing.md

Update docs/pt/testing.md

Update docs/pt/testing.md

Update docs/pt/testing.md

Update docs/pt/testing.md

Update docs/pt/testing.md

Update docs/pt/hot-reload.md

Update docs/pt/hot-reload.md

Update docs/pt/hot-reload.md

Update docs/pt/hot-reload.md

Update docs/pt/hot-reload.md

Update docs/pt/api.md

Update docs/pt/api.md

Update docs/pt/api.md

Update docs/pt/api.md

Update docs/pt/api.md

Revisão da tradução realizada!
Vitor Arjol il y a 9 ans
Parent
commit
a9187155f8

+ 1 - 0
docs/LANGS.md

@@ -1,3 +1,4 @@
 * [English](en/)
 * [简体中文 (outdated)](zh-cn/)
 * [日本語 (outdated)](ja/)
+* [Português](pt/)

+ 1 - 0
docs/pt/README.md

@@ -0,0 +1 @@
+SUMMARY.md

+ 19 - 0
docs/pt/SUMMARY.md

@@ -0,0 +1,19 @@
+# Índice
+
+> Tenha certeza de ler a documentação na ordem a seguir.
+
+- [O que é o Vuex?](intro.md)
+- [Primeiros Passos](getting-started.md)
+- [Tutorial](tutorial.md)
+- Principais Conceitos
+  - [Estado e Getters](state.md)
+  - [Mutações](mutations.md)
+  - [Ações](actions.md)
+- [Fluxo de Dados](data-flow.md)
+- [Estrutura da Aplicação](structure.md)
+- [Middlewares](middlewares.md)
+- [Strict Mode](strict.md)
+- [Manipulação de Formulários](forms.md)
+- [Testes](testing.md)
+- [Hot Reloading](hot-reload.md)
+- [Referência da API](api.md)

+ 134 - 0
docs/pt/actions.md

@@ -0,0 +1,134 @@
+# Ações
+
+> Ações no Vuex são na verdade "action creators" em definições puras do Flux, mas eu achei esse termo mais confuso do que útil.
+
+Ações são apenas funções que disparam mutações. Por convenção, as ações Vuex sempre esperam uma instância de um armazem (store) como primeiro parâmetro, seguido por parâmetros adicionais, que são opcionais:
+
+``` js
+// the simplest action
+function increment (store) {
+  store.dispatch('INCREMENT')
+}
+
+// a action with additional arguments
+// with ES2015 argument destructuring
+function incrementBy ({ dispatch }, amount) {
+  dispatch('INCREMENT', amount)
+}
+```
+
+Isso pode parecer bobo a primeira vista: por que nós simplesmente não disparamos mutações diretamente? Bem, você se lembra que **mutações devem ser síncronas**? Ações não. Nós podemos realizar operações **assíncronas** dentro de uma ação:
+
+``` js
+function incrementAsync ({ dispatch }) {
+  setTimeout(() => {
+    dispatch('INCREMENT')
+  }, 1000)
+}
+```
+
+Um exemplo mais prático seria uma ação para realizar o checkout em um carrinho de compras, o que envolve **chamar uma API assíncrona** e **disparar múltiplas mutações**:
+
+``` js
+function checkout ({ dispatch, state }, products) {
+  // save the current in cart items
+  const savedCartItems = [...state.cart.added]
+  // send out checkout request, and optimistically
+  // clear the cart
+  dispatch(types.CHECKOUT_REQUEST)
+  // the shop API accepts a success callback and a failure callback
+  shop.buyProducts(
+    products,
+    // handle success
+    () => dispatch(types.CHECKOUT_SUCCESS),
+    // handle failure
+    () => dispatch(types.CHECKOUT_FAILURE, savedCartItems)
+  )
+}
+```
+
+Note que ao invés de esperar um retorno ou passar callback para ações, o resultado de chamar uma API assíncrona é lidado ao disparar novas mutações. A política de boa prática vizinhança aqui é que **o único efeito colateral gerado ao chamar ações deve ser disparar mutações**.
+
+### Chamando Ações em Componentes
+
+Você deve ter percebido que uma função de ação não pode ser chamada diretamente sem referenciar uma instância do armazém. Tecnicamente, nós podemos invocar uma ação utilizando `action(this.$store)` dentro de um método, mas é melhor se nós pudermos expor versões de ações diretamente "ligadas" aos métodos dos componentes, e assim nós poderíamos facilmente referenciá-las dentro de templates. Nós podemos fazer isso utilizando a opção `vuex.actions`:
+
+``` js
+// inside a component
+import { incrementBy } from './actions'
+
+const vm = new Vue({
+  vuex: {
+    getters: { ... }, // state getters
+    actions: {
+      incrementBy // ES6 object literal shorthand, bind using the same name
+    }
+  }
+})
+```
+
+O que o código acima faz é vincular a ação `incrementBy` a instância local do armazém do componente, e expô-lo no componente como se fosse um método da instância, acessado via `vm.incrementBy`. Qualquer argumento passado para o método `vm.incrementBy` será passado para a ação que importamos depois do primeiro argumento, que é nosso armazém. Então, ao chamar:
+
+``` js
+vm.incrementBy(1)
+```
+
+é o mesmo que:
+
+``` js
+incrementBy(vm.$store, 1)
+```
+
+Mas o benefício é que nós podemos vincular essa ação ao template do componente e utilizá-lo mais facilmente:
+
+``` html
+<button v-on:click="incrementBy(1)">increment by one</button>
+```
+
+E você pode usar um nome diferente ao método ao vincular uma ação:
+
+``` js
+// inside a component
+import { incrementBy } from './actions'
+
+const vm = new Vue({
+  vuex: {
+    getters: { ... },
+    actions: {
+      plus: incrementBy // bind using a different name
+    }
+  }
+})
+```
+
+Agora a ação será conectada como `vm.plus` ao invés de `vm.incrementBy`.
+
+### Ações Inline
+
+Se uma ação é específica à um componente, você pode utilizar um atalho e definí-la diretamente no componente:
+
+``` js
+const vm = new Vue({
+  vuex: {
+    getters: { ... },
+    actions: {
+      plus: ({ dispatch }) => dispatch('INCREMENT')
+    }
+  }
+})
+```
+
+### Vinculando todas Ações
+
+Se você quiser vincular todas as ações compartilhadas:
+
+``` js
+import * as actions from './actions'
+
+const vm = new Vue({
+  vuex: {
+    getters: { ... },
+    actions // bind all actions
+  }
+})
+```

+ 94 - 0
docs/pt/api.md

@@ -0,0 +1,94 @@
+# Referência da API
+
+### Vuex.Store
+
+``` js
+import Vuex from 'vuex'
+
+const store = new Vuex.Store({ ...options })
+```
+
+### Opções do Construtor Vuex.Store
+
+- **state**
+
+  - tipo: `Objeto`
+
+    O objeto de estado raíz para o armazém Vuex.
+
+    [Detalhes](state.md)
+
+- **mutations**
+
+  - tipo: `Objeto`
+
+    Um objeto onde cada entrada é o nome de uma mutação e o valor é uma função, que é o handler. A função handler sempre recebe o `state` (estado) como primeiro parâmetro, e recebe todos os outros parâmetros passados para a chamada da mutação após esse.
+
+    [Detalhes](mutations.md)
+
+- **modules**
+
+  - tipo: `Objeto`
+
+    Um objeto que contém submódulos para serem combinados dentro do armazém, no seguinte formato:
+
+    ``` js
+    {
+      key: {
+        state,
+        mutations
+      },
+      ...
+    }
+    ```
+
+    Cada módulo pode conter `state` (estado) e `mutations` (mutações) assim como as opções da raíz do Vuex. O estado do módulo será combinado com o estado do armazém principal do Vuex utilizando a opção "modules". As mutações de um módulo somente receberão o estado daquele módulo como primeiro parâmetros, ao invés de todo o estado do armazém.
+
+- **middlewares**
+
+  - tipo: `Array<Objeto>`
+
+    Um array de objetos de middleware que estão no seguinte formato:
+
+    ``` js
+    {
+      snapshot: Boolean, // padrão: false
+      onInit: Function,
+      onMutation: Function
+    }
+    ```
+
+    Todos os campos são opcionais. [Detalhes](middlewares.md)
+
+- **strict**
+
+  - tipo: `Boolean`
+  - padrão: `false`
+
+    Força o armazém do Vuex a se comportar com o modo strict. Quando esse módulo está ativado qualquer mutação ao Vuex que são realizadas fora dos handlers das mutações irão disparar um erro.
+
+    [Detalhes](strict.md)
+
+### Propriedades da Instância Vuex.Store
+
+- **state**
+
+  - tipo: `Objeto`
+
+    O estado raíz. Somente leitura.
+
+### Métodos da Instância Vuex.Store
+
+- **dispatch(mutationName: String, ...args)**
+
+  Dispara diretamente uma mutação. Isso é útil em algumas situações, mas geralmente você ira preferir utilizar as ações no seu código.
+
+- **watch(pathOrGetter: String|Function, cb: Function, [options: Object])**
+
+  Observa um caminho ou o valor de uma função getter, e chama o callback quando o valor é modificado. Aceita opções não obrigatórias idênticas ao do método `vm.$watch` do Vue.
+
+  Para finalizar a observação, chame a função de retorno.
+
+- **hotUpdate(newOptions: Object)**
+
+  Atualização em tempo real de ações e mutações. [Detalhes](hot-reload.md)

+ 1 - 0
docs/pt/book.json

@@ -0,0 +1 @@
+../book.json

+ 89 - 0
docs/pt/data-flow.md

@@ -0,0 +1,89 @@
+# Fluxo de Dados
+
+Vamos construir um simples contador com Vuex para entender um pouco melhor o fluxo de dados dentro de aplicações Vuex. Note que esse é um exemplo trivial somente com o objetivo de explicar os conceitos - na prática você não precisa do Vuex para um app tão simples.
+
+### O Armazém
+
+``` js
+// store.js
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+
+// estado inicial do app
+const state = {
+  count: 0
+}
+
+// definindo as possíveis mutações
+const mutations = {
+  INCREMENT (state) {
+    state.count++
+  },
+  DECREMENT (state) {
+    state.count--
+  }
+}
+
+// criando o armazém
+export default new Vuex.Store({
+  state,
+  mutations
+})
+```
+
+### Ações
+
+``` js
+// actions.js
+export const increment = ({ dispatch }) => dispatch('INCREMENT')
+export const decrement = ({ dispatch }) => dispatch('DECREMENT')
+```
+
+### Utilizando-o com o Vue
+
+**Template**
+
+``` html
+<div id="app">
+  Clicked: {{ count }} times
+  <button v-on:click="increment">+</button>
+  <button v-on:click="decrement">-</button>
+</div>
+```
+
+**Script**
+
+``` js
+// Nós estamos importando e injetando o armazém aqui porque
+// essa é nossa instância raiz. Em aplicações maiores você só precisa fazer isso uma vez.
+import store from './store'
+import { increment, decrement } from './actions'
+
+const app = new Vue({
+  el: '#app',
+  store,
+  vuex: {
+    getters: {
+      count: state => state.count
+    },
+    actions: {
+      increment,
+      decrement
+    }
+  }
+})
+```
+
+Aqui você irá notar que o componente é extremamente simples: Ele exibe um estado do armazém Vuex (nem mesmo tem seus próprios dados), e chama algumas ações do armazém quando o usuário dispara um evento.
+
+Você também irá perceber que o fluxo de dados é unidirecional, como deveria ser no Flux:
+
+1. O input do usuário no componente dispara uma chamada para uma ação;
+2. As Ações disparam mutações que modificam o estado;
+3. As alterações no estado são refletidas no componente via getters.
+
+<p align="center">
+  <img width="700px" src="vuex.png">
+</p>

+ 41 - 0
docs/pt/forms.md

@@ -0,0 +1,41 @@
+# Manipulação de Formulários
+
+Ao utilizar o modo strict do Vuex, é um pouquinho diferente o uso do `v-model`, já que o estado pertence ao Vuex:
+
+``` html
+<input v-model="obj.message">
+```
+
+Assumindo que `obj` é uma computed property que retorna um Objeto do armazém, o `v-model` aqui irá tentar modificar o valor do `obj.message` diretamente quando o usuário digitar algo. Com o modo strict, isso vai resultar em um erro, porque a mutação não é realizada dentro de uma mutação explícita do Vuex.
+
+A maneira "Vuex" de lidar com os formulários é vincular o valor do `<input>`' e chamar uma ação nos eventos `input` ou `change`:
+
+``` html
+<input :value="message" @input="updateMessage">
+```
+``` js
+// ...
+vuex: {
+  getters: {
+    message: state => state.obj.message
+  },
+  actions: {
+    updateMessage: ({ dispatch }, e) => {
+      dispatch('UPDATE_MESSAGE', e.target.value)
+    }
+  }
+}
+```
+
+E aqui é o handler da mutação:
+
+``` js
+// ...
+mutations: {
+  UPDATE_MESSAGE (state, message) {
+    state.obj.message = message
+  }
+}
+```
+
+Sim, isso é bem mais extenso do que simplesmente utilizar um `v-model`, mas esse é o custo de fazer com que as modificações do estado sejam explícitas e rastreáveis. Ao mesmo tempo, note que o Vuex não demanda que você adicione todo o estado no armazém - se você não quiser rastrear mas mutações para as interações de formulário, você pode simplesmente manter o estado do formulário fora do Vuex como o estado local do componente, o que lhe permite utilizar livremente o `v-model`.

+ 53 - 0
docs/pt/getting-started.md

@@ -0,0 +1,53 @@
+# Getting Started
+
+No centro de cada aplicação Vuex existe um "armazém", que você verá nos exemplos como **store**. Um "armazem" é basicamente um container que armazena o **estado** da sua aplicação. Existem duas coisas que fazem esse armazem do Vuex ser diferente de um objeto global simples:
+
+1. Os "armazéns" do Vuex são reativas. Quando os componentes Vue recuperam o estado a partir dele, eles irão funcionar reativamente e realizarão uma atualização eficientemente se o estado for modificado no armazém.
+
+2. Você não pode modificar o estado do armazém diretamente. A única forma de alterar o estado é disparando **mutações** explicitamente. Isso faz com que cada mudança no estado seja fácil de ser gravada, e possibilita o uso de ferramentas que nos ajude a compreender melhor nossas aplicações.
+
+### O armazém mais simples
+
+> **NOTA:** Nós utilizaremos a sintaxe do ES2015 para exemplos de código em toda a documentação. Se você ainda não aprendeu a utilizá-lo, [você deveria](https://babeljs.io/docs/learn-es2015/)! Essa documentação também assume que você está familiarizado com os conceitos discutidos em [Construindo Aplicações de Larga Escala com Vue.js](http://vuejs.org/guide/application.html).
+
+Criar um armazem Vuex é bem simples. Você apenas precisa informar um objeto que é seu estado inicial, e alguma mutação:
+
+``` js
+import Vuex from 'vuex'
+
+const state = {
+  count: 0
+}
+
+const mutations = {
+  INCREMENT (state) {
+    state.count++
+  }
+}
+
+export default new Vuex.Store({
+  state,
+  mutations
+})
+```
+
+Agora, você pode acessar o objeto que contém o estado como `store.state`, e disparar uma mutação utilizando o método <i>dispatch</i> e o nome da aplicação:
+
+``` js
+store.dispatch('INCREMENT')
+
+console.log(store.state.count) // -> 1
+```
+
+Se você preferir utilizar o formato de objeto para os parâmetros, você pode utilizar o exemplo a seguir:
+
+``` js
+// O mesmo efeito que o exemplo anterior
+store.dispatch({
+  type: 'INCREMENT'
+})
+```
+
+Novamente, a razão para nós dispararmos uma mutação ao invés de modificar diretamente o valor de `store.state.count` é porque queremos explicitamente rastrear a modificação. Essa simples convenção faz com que suas intenções fiquem mais explícitas, e assim você pode compreender as modificações do estado mais facilmente quando ler seu código. Além disso, isso nos dá a oportunidade de implementar ferramentas que podem realizar um log para todas as mutações, tirar <i>snapshots</i> do estado e até mesmo utilizar <i>time travel debugging</i>.
+
+Agora esse é apenas uma simples exemplo do que é um armazém Vuex. Mas o Vuex é bem mais do que isso. A seguir, iremos discutir alguns dos conceitos principais mais a fundo: [Estado](state.md), [Mutações](mutations.md) e [Ações](actions.md).

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

@@ -0,0 +1,44 @@
+# Hot Reloading
+
+Vuex suporta hot-reloading para mutações, módulos, ações e getters durante desenvolvimento, utilizando o [Hot Module Replacement API](https://webpack.github.io/docs/hot-module-replacement.html) do Wepack. Você também pode utilizar com Browserify utilizando o plugin [browserify-hmr](https://github.com/AgentME/browserify-hmr/).
+
+Para mutações e módulos, você precisa utilizar o método `store.hotUpdate()` da 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) {
+  // accept actions and mutations as hot modules
+  module.hot.accept(['./mutations', './modules/a'], () => {
+    // require the updated modules
+    // have to add .default here due to babel 6 module output
+    const newMutations = require('./mutations').default
+    const newModuleA = require('./modules/a').default
+    // swap in the new actions and mutations
+    store.hotUpdate({
+      mutations: newMutations,
+      modules: {
+        a: newModuleA
+      }
+    })
+  })
+}
+```
+
+Você não precisa fazer nada em específico para ações e getters. O sistema de substituição do Webpack's vai lidar com toda a parte das atualizações - e as mudanças em ações e getters irão ocorrer automaticamente nos componentes Vue que utilizam-nas. Como os componentes Vue carregados via `vue-loader` são recarregados automaticamente, esses componentes que forem afetados com mudanças vão se recarregar automaticamente e utilizarão as ações e getters mais recentes.

+ 13 - 0
docs/pt/intro.md

@@ -0,0 +1,13 @@
+## O que é o Vuex?
+
+Vuex é uma arquitetura de aplicações para gerenciamento de estado centralizado em aplicações Vue.js. Foi desenvolvido inspirado no [Flux](https://facebook.github.io/flux/) e também no [Redux](https://github.com/rackt/redux), mas com conceitos simplificados e com uma implementação que foi feita especificamente para utilizar as vantagens do sistema de reatividade do Vue.js
+
+## Por que eu preciso disso?
+
+Se o seu aplicativo for simples, você provavelmente não precisa utilizar o Vuex. Não o aplique prematuramente. Mas se você estiver construindo uma SPA (Single Page Application) de médio a grande porte, é bem provável que você lidará com situações que lhe farão pensar como estruturar sua aplicação fora dos seus componentes Vue. E é aí que o Vuex entra em cena.
+
+Quando utilizamos somente o Vue.js, nós geralmente armazenamos o estado da aplicação "dentro" de nossos componentes. Isso significa que cada componente é dona de uma parte do estado de nossa aplicação, e como resultado disso é que o estado fica espalhado por toda a aplicação. Entretanto, algumas vezes você precisa compartilhar parte do estado com vários componentes. Uma prática muito utilizada é deixar que o componente "emita" um evento para outro componente e compartilhe parte do estado. O problema com esse padrão é que o fluxo de evento dentro de aplicações mais complexas com vários componentes começa a se tornar confuso e difícil de compreender, e isso pode induzir você a erros.
+
+Para lidar com o estado em aplicações complexas, nós precisamos diferenciar o **estado do componente local** e **o estado da aplicação**. O estado da Aplicação não pertence a um componente específico, mas nossos componentes ainda podem observá-lo para realizar updates reativos no DOM. Ao centralizar o seu gerenciamento em um local, nós não precisamos mais emitir eventos para transmitir dados, porque tudo que afeta mais que um componente deve percenter ao estado da Aplicação. Além disso, isso nos permite gravar e inspecionar todas as mutações para compreender melhor as mudanças no estado, e até implementar coisas mais interessantes como o <i>time-travel debugging</i>.
+
+O Vuex também é explícito em relação a como você deve separar a lógica de gerenciamento de estado em diferentes arquivos, porém tem flexibilidade suficiente para que você o aplique em seu código atual.

+ 82 - 0
docs/pt/middlewares.md

@@ -0,0 +1,82 @@
+# Middlewares
+
+Os armazéns Vuex aceitam a opção `middlewares` que expõem hooks para cada mutação (Note que isso é completamente não relacionado aos middlewares Redux). Um middleware Vuex é simplesmente um objeto que implementam algumas funções de hook:
+
+``` js
+const myMiddleware = {
+  onInit (state, store) {
+    // estado inicial do registro
+  },
+  onMutation (mutation, state, store) {
+    // chamado após todas mutações
+    // A mutação vem no formato { type, payload }
+  }
+}
+```
+
+E também pode ser utilizado assim:
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  middlewares: [myMiddleware]
+})
+```
+
+Por padrão, um middleware recebe o objeto `state` real. Um middleware também pode receber o `armazém` (`store`) para disparar mutações. Como os middlewares são primariamente utilizados para debug da sua aplicação ou persistência de dados, eles **não podem modificar o estado**
+
+Algumas vezes um middleware pode querer receber <i>"snapshots"</i> do estado, e também comparar o estádo pós-mutação com o pré-mutação. Esses middlewares precisam declarar a opção `snapshot: true`:
+
+``` js
+const myMiddlewareWithSnapshot = {
+  snapshot: true,
+  onMutation (mutation, nextState, prevState, store) {
+    // nextState and prevState are deep-cloned snapshots
+    // of the state before and after the mutation.
+  }
+}
+```
+
+**Middlwares que fazem snapshots devem apenas serem utilizados durante desenvolvimento** Quando você estiver utilizando Webpack ou o Browserify, você pode deixar que essas ferramentas cuidem disso para você:
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  middlewares: process.env.NODE_ENV !== 'production'
+    ? [myMiddlewareWithSnapshot]
+    : []
+})
+```
+
+O middleware será utilizado por padrão. Para produção, utilize a build descrita [aqui](http://vuejs.org/guide/application.html#Deploying_for_Production) para converter o valor de `process.env.NODE_ENV !== 'production'` para `false` na build final.
+### Middleware de Log Padrão
+
+O Vuex já vem com um middleware de log para o uso geral de debug:
+
+``` js
+import createLogger from 'vuex/logger'
+
+const store = new Vuex.Store({
+  middlewares: [createLogger()]
+})
+```
+
+A função `createLogger` recebe alguns parâmetros:
+
+``` js
+const logger = createLogger({
+  collapsed: false, // auto-expand logged mutations
+  transformer (state) {
+    // transform the state before logging it.
+    // for example return only a specific sub-tree
+    return state.subTree
+  },
+  mutationTransformer (mutation) {
+    // mutations are logged in the format of { type, payload }
+    // we can format it anyway we want.
+    return mutation.type
+  }
+})
+```
+
+Note que o middleware logger faz <i>snapshots</i> do estado, então utilize-o apenas para desenvolvimento.

+ 134 - 0
docs/pt/mutations.md

@@ -0,0 +1,134 @@
+# Mutações
+
+Mutações do Vuex são essenciamente eventos? cada mutação tem um **nome** e um **handler**. A função handler irá receber o estado como primeiro parâmetro:
+
+``` js
+import Vuex from 'vuex'
+
+const store = new Vuex.Store({
+  state: {
+    count: 1
+  },
+  mutations: {
+    INCREMENT (state) {
+      // mutate state
+      state.count++
+    }
+  }
+})
+```
+
+Utilizar apenas letras para nomes de mutações é apenas uma convenção para fazer com que seja mais fácil diferenciá-las de simples funções.
+
+Você não pode chamar diretamente um handler de mutação. As opções aqui são mais parecidas com um registro de um evento: "Quando um evento `INCREMENT` é disparado, chame esse handler". Para invocar um handler de uma mutação, você precisa disparar um evento de mutação:
+
+``` js
+store.dispatch('INCREMENT')
+```
+
+### Disparando Eventos com Argumentos
+
+Também é possível passar parâmetros para o handler:
+
+``` js
+// ...
+mutations: {
+  INCREMENT (state, n) {
+    state.count += n
+  }
+}
+```
+``` js
+store.dispatch('INCREMENT', 10)
+```
+
+Aqui o valor `10` será passado para o handler da mutação como o segundo arumento, já que o primeiro sempre será o `state`. O mesmo serve para qualquer parâmetro adicional. Esses parâmetros são chamados de **payload**.
+
+### Disparando no Estilo Objeto
+
+> necessita do vuex >=0.6.2
+
+Você também pode disparar mutações utilizando objetos:
+
+``` js
+store.dispatch({
+  type: 'INCREMENT',
+  payload: 10
+})
+```
+
+Note que ao utilizar o estilo objeto, você deve incluir todos os argumentos como propriedades no objeto despachado. O objeto inteiro será passado como o segundo parâmetro para os handlers das mutações:
+
+``` js
+mutations: {
+  INCREMENT (state, mutation) {
+    state.count += mutation.payload
+  }
+}
+```
+
+### Mutações seguem as regras de Reatividade do Vue.js
+
+Como um armazém de estado Vuex é feito reativo pelo Vue, quando nós mudamos o estado, os compoentes Vue que estão observando-o irão atualizar automaticamente. Isso também significa que as mutações do Vuex estão subjetivas para as mesmas regras e ressalvas de quando utilizamos apenas o Vue.js
+Since a Vuex store's state is made reactive by Vue, when we mutate the state, Vue components observing the state will update automatically. This also means Vuex mutations are subject to the same reactivity caveats when working with plain Vue:
+
+1. Prefira inicializar o estado inicial do seu armazém com todos os campos definidos previamente.
+
+2. Ao adicionar novas propriedades para um objeto, você deve seguir uma das duas opções abaixo:
+
+  - Utilize `Vue.set(obj, 'newProp', 123)`, ou -
+
+  - Substitua o objeto antigo por um novo. Por exemplo, utilizando o stage-2 [object spread syntax](https://github.com/sebmarkbage/ecmascript-rest-spread) nós poderíamos escrever assim:
+
+  ``` js
+  state.obj = { ...state.obj, newProp: 123 }
+  ```
+
+### Utilizando Constantes para nomes de Mutações
+
+Também é uma prática comum utilizar constantes para os nomes das mutações - elas irão permitir que o código tome vantagens de ferramentas como linters, e colocar todas as constantes em um único arquivo permite que seus colaboradores possam ter uma visualização geral de todas as mutações que são possíveis em sua aplicação:
+
+``` 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: { ... },
+  actions: { ... },
+  mutations: {
+    // we can use the ES2015 computed property name feature
+    // to use a constant as the function name
+    [SOME_MUTATION] (state) {
+      // mutate state
+    }
+  }
+})
+```
+
+Whether to use constants is largely a preference - it can be helpful in large projects with many developers, but it's totally optional if you don't like them.
+
+### Mutações Precisam ser Síncronas
+
+Uma regra importante para se lembrar é que **o handler de uma mutação sempre deve ser síncrono**. Por que? Considere o exemplo a seguir:
+
+``` js
+mutations: {
+  SOME_MUTATION (state) {
+    api.callAsyncMethod(() => {
+      state.count++
+    })
+  }
+}
+```
+
+Agora imagine que nós estamos debugando o app e olhando nosso log de mutações. Para todas as mutações que estão no log, nós queremos compará-las com <i>snapshots</i> do estado *antes* e *depois* da mutação. Entretanto, os callbacks assíncronos dentro do exemplo de mutação acima faz com que isso seja impossível: o callback não é chamado quando a mutação é disparada, e nós não sabemos quando o callback será chamado de verdade. Qualquer mutação no estado que for realizada no callback é essencialmente irrastreável!
+
+### Ações
+
+Assincronidade combinada com mutações do estado podem fazer nossa aplicação ser de difícil compreensão. Por exemplo, quando você chama dois métodos, e ambos possuem callbacks assíncronos para modificar o estado, como você sabe qual método foi chamado e qual callback foi executado primeiro? É por isso que nós separamos os dois conceitos. Com o Vuex, nós realizamos todas as mutações no estado de forma síncrona. Nós iremos realizar qualquer ação assíncrona dentro de [Ações](actions.md).

+ 156 - 0
docs/pt/state.md

@@ -0,0 +1,156 @@
+# Estado and Getters
+
+### Árvore única de estado
+
+O Vuex utiliza uma **árvore única de estado** - ou seja, esse único objeto contém todo estado do nível de Aplicação e funciona como uma "fonté única de verdade". Isso também significa que você terá somente um armazém por aplicação. Uma única árvore de estado faz com seja simples localizar uma parte específica do seu estado, e nos permite facilmente tirar <i>snapshots</i> da aplicação para debugar.
+
+A árvore única de estado não é conflitante com o conceito de modularidade - nos próximos capítulos nós iremos discutir como separar o estado e as mutações em submódulos.
+
+### Recuperando Estado do Vuex em Componentes Vue
+
+Então como nós exibimos o estado do armazém em nossos componentes Vue? Já que os armazéns são reativos, a forma mais simples de "recupearar" o estado dele é simplesmente retornar o estado a partir de uma [computed property](http://vuejs.org/guide/computed.html):
+
+``` js
+// na definição de um componente Vue
+computed: {
+  count: function () {
+    return store.state.count
+  }
+}
+```
+
+A qualquer momento que o valor de `store.state.count` for modificado, ele irá obrigar a <i>computed property</i>, a se atualizar, e irá disparar as mudanças nos DOM's associados.
+
+Entretanto, esse padrão faz com que o componente esteja ligado com a instância única global do armazém. Isso faz com que seja mais difcíl para testar o componente, e também mais difícil para executar múltiplas instâncias do aplicativo utilizando o mesmo conjunto de componentes. Em aplicações maiores, nós provavelmente iremos preferir "injetar" o armazém em componentes filhos. Você pode fazer como no exeplo a seguir:
+
+1. Instale o Vuex e conecte seu componente raíz ao armazém:
+
+  ``` js
+  import Vue from 'vue'
+  import Vuex from 'vuex'
+  import store from './store'
+  import MyComponent from './MyComponent'
+
+  // important, teaches Vue components how to
+  // handle Vuex-related options
+  Vue.use(Vuex)
+
+  var app = new Vue({
+    el: '#app',
+    // provide the store using the "store" option.
+    // this will inject the store instance to all child components.
+    store,
+    components: {
+      MyComponent
+    }
+  })
+  ```
+
+  Ao informar a opção `store` para a instância principal, o armazém será injetado em todos os componentes filhos da instância principal e estará disponível neles a partir da opção `this.$store`. Entretando, dificilmente você terá que referenciá-lo.
+
+2. Dentro dos componentes filhos, recupere o estado utilizando funções **getter** na opção `vuex.getters`:
+
+  ``` js
+  // MyComponent.js
+  export default {
+    template: '...',
+    data () { ... },
+    // this is where we retrieve state from the store
+    vuex: {
+      getters: {
+        // a state getter function, which will
+        // bind `store.state.count` on the component as `this.count`
+        count: function (state) {
+          return state.count
+        }
+      }
+    }
+  }
+  ```
+
+  Note o bloco de opções especial chamado `vuex`. É aqui que nós especificamos qual estado o componente estará utilizando do armazem. Para cada propriedade, nós especificamos uma função <i>getter</i> que recebe a árvore de estados como argumento único, e então seleciona e retorna parte do estado, ou um valor computado derivado do estado. O resultado retornado será setado no componente utilizando uma propriedade nomeada, como uma computed property.
+
+  Em vários casos, a função "getter" pode ser bem sucinta utilizando as arrow functions do ES2015:
+
+  ``` js
+  vuex: {
+    getters: {
+      count: state => state.count
+    }
+  }
+  ```
+
+### Getters Devem ser puros
+
+Todos os getters Vuex devem ser [funções puras](https://en.wikipedia.org/wiki/Pure_function) - eles recebem toda a árove de estados, e retornam um valor baseado somente no estado. Isso faz com que elas sejam mais testáveis e eficientes. Isso também significa que **você não pode utilizar o `this` em getters**.
+
+Se você precisar acessar o `this`, por exemplo, para computar um estado derivado baseado no estado do componente local ou propriedades deles, você precisa definir computed properties separadas:
+
+``` js
+vuex: {
+  getters: {
+    currentId: state => state.currentId
+  }
+},
+computed: {
+  isCurrent () {
+    return this.id === this.currentId
+  }
+}
+```
+
+### Getters Podem retornar estado derivado
+
+No Vuex, Getters de estado na verdade são computed, e isso significa que você pode utilizá-los de forma reativa (e eficiente) como uma computed property. Por exemplo, vamos dizer que no estado nós possuímos um array de mensagens chamado `messages`, e um `currentThreadID` representando a conversa atual que o usuário está participando. Nós queremos exibir para o usuário uma listra de mensagens filtradas que são referentes a conversa atual:
+
+``` js
+vuex: {
+  getters: {
+    filteredMessages: state => {
+      return state.messages.filter(message => {
+        return message.threadID === state.currentThreadID
+      })
+    }
+  }
+}
+```
+
+Como as Computed properties do Vue js ficam em cache automaticamente e são apenas atualizadas quando uma dependência é modificada, você não precisa se preocupar com essa função sendo chamada em todas as mutações.
+
+### Compartilhando Getters em Múltiplos Componentes
+
+Como você pode ver, o getter `filteredMessages` pode ser útil dentro de vários componentes. Nesse caso, é uma boa ideia compartilhar essa função entre esses componentes:
+
+``` js
+// getters.js
+export function filteredMessages (state) {
+  return state.messages.filter(message => {
+    return message.threadID === state.currentThreadID
+  })
+}
+```
+
+``` js
+// in a component...
+import { filteredMessages } from './getters'
+
+export default {
+  vuex: {
+    getters: {
+      filteredMessages
+    }
+  }
+}
+```
+
+Como os getters são puros, getters compartilhados são colocados em cache de forma eficiente: quando as dependências mudam, eles só precisam se atualizar uma vez e todos os componentes terão o valor atualizado.
+
+> Referência Flux: Os getters do Vuex podem ser mais ou menos comparados com [`mapStateToProps`](https://github.com/rackt/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options) on Redux. Entretando, como eles utilizam o sistema do Vue.js para computed properties por trás das cortinas, eles são mais eficientes que o `mapStateToProps`, e mais similares ao [reselect](https://github.com/reactjs/reselect).
+
+### Componentes Não São Permitidos a Modificarem o Estado Diretamente
+
+É importante se lembrar que **componentes nunca devem modificar o estado do armazém Vuex diretamente**. Já que nós queremos que todas as mutações sejam explícitas e rastreáveis, todas as mutações de estado no Vuex devem ser conduzidas dentro dos handlers das mutações do armazém..
+
+Para ajudar a "obrigar" essa regra, quando você estiver com o [Strict Mode](strict.md) habilitado, se o estado do armazém é modificado fora dos handlers de mutação, o Vuex vai disparar um erro.
+
+Com essa regra ativa, nossos componentes Vue agora tem muito menos responsabilidades: eles estão ligados ao armazém de estado do Vuex com getters apenas de leitura, e a única maneira para eles modificarem o estado é de alguma forma disparando **mutações** (que nós vamos discutir mais tarde). Eles ainda podem conter e modificar seu estado local se necessário, mas nós não colocamos nenhuma lógica para buscar dados ou modificar o estado global dentro de componentes individuais. Eles agora estão centralizados nos arquivos relacionados ao Vuex, o que torna aplicações grandes e complexas fáceis de se entender e manter.

+ 25 - 0
docs/pt/strict.md

@@ -0,0 +1,25 @@
+# Strict Mode
+
+Para habilitar o modo Strict, simplesmente passe a opção `strict: true` ao criar um armazém Vuex:
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  strict: true
+})
+```
+
+Com o modo strict habilitado, sempre que o estado do Vuex for mutado fora dos handlers de mutação, um erro será disparado. Isso nos garante que todas as mutações do estado possam ser explicitamente rastreada por ferramentas de debug.
+
+### Desenvolvimento vs. Produção
+
+**Não habilite o modo strict quando enviar seu app para produção!** O modo Strict utiliza um estado de ampla "visão" (deep watch) no seu código para garantir que nenhuma mutação inapropriada ocorra - tenha certeza de desabilitar o seu uso para produção para evitar que o seu uso faça com que seu app fique lento.
+
+Assim como os middlewares, nós podemos deixar com que as ferramentas de build do seu código lidem com isso:
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  strict: process.env.NODE_ENV !== 'production'
+})
+```

+ 136 - 0
docs/pt/structure.md

@@ -0,0 +1,136 @@
+# Estrutura da Aplicação
+
+O Vuex não te restringe em como estruturar seu código. Em vez disso, ele impõe um conjunto de princípios de alto nível:
+
+1. O estado da aplicação é mantido no armazém, que é um único objeto.
+
+2. A única maneira de modificar o estado é disparando mutações no armazém.
+
+3. Mutações devem ser síncronas, e o único efeito colateral que elas devem produzir deve ser a mutação do estado.
+
+4. Nós podemos expor uma API de mutação do estado mais expressiva ao definir ações. Ações podem encapsular lógica assíncrona como carregamento de dados, e o único efeito colateral que elas devem produzir é disparar mutações.
+
+5. Componentes usam getters para recuperar estado do armazém, e chamar ações para modificar o estado.
+
+Um fato legal sobre mutações Vuex, ações e getters é que **eles são apenas funções**. Desde que você siga essas regras, você é quem decide como estruturar sua aplicação. Entretando, é bom termos algumas convenções, assim você se torna familiar a outros projetos que utilizem o Vuex. Abaixo você vê algumas opções dependendo do tamanho do seu aplicativo.
+
+### Projeto Simples
+
+Para um projeto simples, nós podemos simplesmente definir o **armazém** e as **ações** em seus respectivos arquivos:
+
+``` bash
+.
+├── index.html
+├── main.js
+├── components
+│   ├── App.vue
+│   └── ...
+└── vuex
+    ├── store.js     # exporta todo o armazém (com seu estado inicial e suas mutações)
+    └── actions.js   # exporta todas ações
+```
+
+Para um exemplo real, veja o exemplo do [Contador](https://github.com/vuejs/vuex/tree/master/examples/counter) ou o exemplo do [TodoMVC](https://github.com/vuejs/vuex/tree/master/examples/todomvc).
+
+Como alternativa, você pode separar as mutações para seu próprio arquivo.
+
+### De médio a grande porte
+
+Para um app não trivial, nós provavelmente queremos dividir o código relacionado ao Vuex em vários "módulos" (comparáveis a "stores" no Flux, e "reducers" no Redux), cada um lidando com uma parte específica da sua aplicação. Cada módulo estará gerenciando uma parte da árvore do estado da aplicação, exportando o estado inicial para aquela parte da aplicação e todas as mutações que são relativas a ela:
+
+``` bash
+├── index.html
+├── main.js
+├── api
+│   └── ... # abstrações para realizar requisições para a API
+├── components
+│   ├── App.vue
+│   └── ...
+└── vuex
+    ├── actions.js        # exporta todas ações
+    ├── store.js          # onde nós reunimos os módulos e exportamos o armazém
+    ├── mutation-types.js # constantes
+    └── modules
+        ├── cart.js       # estados e mutações para o carrinho
+        └── products.js   # estados e mutações para os produtos
+```
+
+Um módulo se parece com esse exemplo:
+
+``` js
+// vuex/modules/products.js
+import {
+  RECEIVE_PRODUCTS,
+  ADD_TO_CART
+} from '../mutation-types'
+
+// initial state
+const state = {
+  all: []
+}
+
+// mutações
+const mutations = {
+  [RECEIVE_PRODUCTS] (state, products) {
+    state.all = products
+  },
+
+  [ADD_TO_CART] (state, productId) {
+    state.all.find(p => p.id === productId).inventory--
+  }
+}
+
+export default {
+  state,
+  mutations
+}
+```
+
+E no arquivo `vuex/store.js`, nós "juntamos" vários módulos para criar a instância Vuex :
+
+``` js
+// vuex/store.js
+import Vue from 'vue'
+import Vuex from '../../../src'
+// importando partes de módulos
+import cart from './modules/cart'
+import products from './modules/products'
+
+Vue.use(Vuex)
+
+export default new Vuex.Store({
+  // combinando submódulos
+  modules: {
+    cart,
+    products
+  }
+})
+```
+
+Aqui, o estado inicial para o módulo `cart` será anexado à arvore de estado como `store.state.cart`. Além disso, **todas as mutações definidades em um submódulo somente recebem a parte do estado da aplicação que está associada a elas**. Então mutações definidas no módulo `cart` irão receber `store.state.cart` como seu primeiro parâmetro.
+
+A raíz de uma subárvore de estado não é substituível dentro do próprio módulo. Por exemplo, o código abaixo não funcionaria:
+
+``` js
+const mutations = {
+  SOME_MUTATION (state) {
+    state = { ... }
+  }
+}
+```
+
+Ao invés disso, sempre armazene o estado atual como uma propriedade da raíz da subárvore:
+
+``` js
+const mutations = {
+  SOME_MUTATION (state) {
+    state.value = { ... }
+  }
+}
+```
+
+Como todos os módulos simplesmente exportam objetos e funções, eles são bem simples de testar e manter, e pode utilizar o hot-reload. Você também tem a liberdade de alterar os padrões utilizados aqui para encontrar a estrutura que se encaixe nas suas preferências.
+
+Note que nós não inserimos ações dentro de módulos, porque uma simples ação pode disparar mutações que afetem vários módulos. Também é uma boa ideia desacoplar as ações do seu estado e dos detalhes de implementação das mutações para uma melhor separação de conceitos. Se os arquivos das ações ficarem muito extensos, você pode criar uma pasta e dividir a implementação em pequenos arquivos individuais..
+
+Para um exemplo real, veja o [Exemplo de Carrinho de Compras](https://github.com/vuejs/vuex/tree/master/examples/shopping-cart).

+ 167 - 0
docs/pt/testing.md

@@ -0,0 +1,167 @@
+ # Testes
+
+As partes principais que nós queremos testar no Vuex são as mutações e as ações.
+
+### Testando Mutações
+
+Mutações são muito fáceis de testar, porque elas são apenas funções que dependem apenas de seus parâmetros. Uma dica é que se você estiver utilizando módulos ES2015 e colocar suas mutações dentro do seu arquivo `store.js`, além dos dados que são exportados por padrão, você também pode exportar mutações nomeadas:
+
+``` js
+const state = { ... }
+
+// exportando as mutações com nomes
+export const mutations = { ... }
+
+export default new Vuex.Store({
+  state,
+  mutations
+})
+```
+
+Exemplo de testes de mutação utilizando Mocha + Chai (você pode usar qualquer framework/bibliotecas de teste que você quiser):
+
+``` js
+// mutations.js
+export const INCREMENT = state => state.count++
+```
+
+``` js
+// mutations.spec.js
+import { expect } from 'chai'
+import { mutations } from './store'
+
+// destructure assign mutations
+const { INCREMENT } = mutations
+
+describe('mutations', () => {
+  it('INCREMENT', () => {
+    // mock state
+    const state = { count: 0 }
+    // apply mutation
+    INCREMENT(state)
+    // assert result
+    expect(state.count).to.equal(1)
+  })
+})
+```
+
+### Testando Ações
+
+Ações podem ser um pouco mais complicadas de testar porque talvez elas chamem APIs externas. Ao testar ações, nós geralmente precisamos realizar algum tipo de mocking - por exemplo, nós podemos abstrair as chamadas da api em um serviço e usar um mock para esse serviço em nossos testes. Para facilitar esse processo, você pode utizar o Webpack em conjunto com o [inject-loader](https://github.com/plasticine/inject-loader) para empacotar os arquivos de testes.
+
+Exemplo de teste com uma ação assíncrona:
+
+``` js
+// actions.js
+import shop from '../api/shop'
+
+export const getAllProducts = ({ dispatch }) => {
+  dispatch('REQUEST_PRODUCTS')
+  shop.getProducts(products => {
+    dispatch('RECEIVE_PRODUCTS', products)
+  })
+}
+```
+
+``` js
+// actions.spec.js
+
+// use require syntax for inline loaders.
+// with inject-loader, this returns a module factory
+// that allows us to inject mocked dependencies.
+import { expect } from 'chai'
+const actionsInjector = require('inject!./actions')
+
+// create the module with our mocks
+const actions = actionsInjector({
+  '../api/shop': {
+    getProducts (cb) {
+      setTimeout(() => {
+        cb([ /* mocked response */ ])
+      }, 100)
+    }
+  }
+})
+
+// helper for testing action with expected mutations
+const testAction = (action, args, state, expectedMutations, done) => {
+  let count = 0
+  // mock dispatch
+  const dispatch = (name, ...payload) => {
+    const mutation = expectedMutations[count]
+    expect(mutation.name).to.equal(name)
+    if (payload) {
+      expect(mutation.payload).to.deep.equal(payload)
+    }
+    count++
+    if (count >= expectedMutations.length) {
+      done()
+    }
+  }
+  // call the action with mocked store and arguments
+  action({dispatch, state}, ...args)
+
+  // check if no mutations should have been dispatched
+  if (count === 0) {
+    expect(expectedMutations.length).to.equal(0)
+    done()
+  }
+}
+
+describe('actions', () => {
+  it('getAllProducts', done => {
+    testAction(actions.getAllProducts, [], {}, [
+      { name: 'REQUEST_PRODUCTS' },
+      { name: 'RECEIVE_PRODUCTS', payload: [ /* mocked response */ ] }
+    ], done)
+  })
+})
+```
+
+### Rodando os Testes
+
+Se suas mutações e ações forem escritas corretamente, os testes não devem ter nenhuma dependÊncia direta nas APIs dos navegadores após o mocking bem realizado. Assim, você pode simplesmente agrupar os testes com Webpack e executá-lo diretamente no Node. Alternativamente, você pode utilizar o `mocha-loader` ou o Karma + `karma-webpack` para rodar os testes em um navegador real.
+
+#### Testando no Node
+
+Crie a seguinte configuração no webpack:
+
+``` js
+module.exports = {
+  entry: './test.js',
+  output: {
+    path: __dirname,
+    filename: 'test-bundle.js'
+  },
+  module: {
+    loaders: [
+      {
+        test: /\.js$/,
+        loader: 'babel',
+        exclude: /node_modules/
+      }
+    ]
+  },
+  babel: {
+    presets: ['es2015']
+  }
+}
+```
+
+Então:
+
+``` bash
+webpack
+mocha test-bundle.js
+```
+
+#### Testando no Navegador
+
+1. Instale o `mocha-loader`
+2. Mude o valor da opção `entry` na configuração acima do Webpack para `'mocha!babel!./test.js'`.
+3. Inicie o `webpack-dev-server` usando a configuração
+4. Va até o endereço `localhost:8080/webpack-dev-server/test-bundle`.
+
+#### Testando no Navegador com Karma + karma-webpack
+
+Consulte o setup na [documentação do vue-loader](http://vuejs.github.io/vue-loader/workflow/testing.html).

+ 266 - 0
docs/pt/tutorial.md

@@ -0,0 +1,266 @@
+# Tutorial
+
+ Vamos criar um app bem simples utilizando o Vuex para entender como utilizá-lo. Para esse exemplo, nós iremos construir um aplicativo onde você pressiona um botão, e ele incrementa um contador.
+
+![Resultado Final](tutorial/result.png)
+
+Nós estaremos utilizando esse simples exemplo para explicar os conceitos, e os problemas que o vuex tenta resolver - como gerenciar um aplicativo complexo que utiliza vários componentes. Considere que esse exemplo utiliza três componentes:
+
+### `components/App.vue`
+
+O elemento raíz, que contém outros dois componentes filhos:
+
+* `Display` para exibir o valor atual do contador.
+* `Increment` que é um botão para incrementar o valor atual.
+
+```html
+<template>
+  <div>
+    <Display></Display>
+    <Increment></Increment>
+  </div>
+</template>
+
+<script>
+
+import Display from './Display.vue'
+import Increment from './Increment.vue'
+
+export default {
+  components: {
+    Display: Display,
+    Increment: Increment
+  }
+}
+</script>
+```
+
+### `components/Display.vue`
+
+```html
+<template>
+  <div>
+    <h3>Count is 0</h3>
+  </div>
+</template>
+
+<script>
+export default {
+}
+</script>
+```
+
+### `components/Increment.vue`
+
+```html
+<template>
+  <div>
+    <button>Increment +1</button>
+  </div>
+</template>
+
+<script>
+export default {
+}
+</script>
+```
+
+### Desafios sem o vuex
+
+* `Increment` e `Display` não sabem da existência um do outro, e não podem passar mensagens entre si.
+* `App` terá que utilizar <i>events</i> e <i>broadcasts</i> para coordenar os dois componentes.
+* Já que o `App` é quem coordena os outros componentes, eles não são reutilizáveis e são muito acoplados. Reestruturar o aplicativo pode quebrá-lo.
+
+### "Fluxo" Vuex
+
+Esses são os passos que serão utilizados:
+
+![Vuex Flow](tutorial/vuex_flow.png)
+
+Isso pode ser um pouco demais para incrementar um contador. Mas note que esses conceitos irão funcionar muito bem em aplicações maiores, melhorando a manutenabilidade e fazendo seu aplicativo mais fácil de debugar e vai te ajudar a manter ele por mais tempo. Então, vamos modificar nosso código para utilizar o Vuex.
+
+### Passo 1: Adicione um Armazém
+
+O armazém mantém os dados do aplicativo. Todos os componentes utilizam os dados do armazém. Antes de começarmos, instale o Vuex via npm:
+
+```
+$ npm install --save vuex
+```
+
+Crie um novo arquivo em `vuex/store.js`
+
+```js
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+// Indique o Vue a utilizar o Vuex
+Vue.use(Vuex)
+
+// Nós criamos um objeto para armazenar o valor inicial do estado
+// quando o aplicativo for iniciado
+const state = {
+  // TODO: Adicionar o estado inicial
+}
+
+// Crie um objeto para armazenar nossas mutações.
+const mutations = {
+  // TODO: adicionar as mutações
+}
+
+// Vamos combinar o estado inicial com as mutações para criar um armazém Vuex
+// Esse armazém pode ser vinculado ao aplicativo
+export default new Vuex.Store({
+  state,
+  mutations
+})
+```
+
+Nós precisamos informar ao nosso aplicativo sobre esse armazém. Para fazer isso nós simplesmente precisamos alterar nosso componente principal.
+
+Edite o arquivo `components/App.vue` e adicione o armazém.
+
+```js
+import Display from './Display.vue'
+import Increment from './IncrementButton.vue'
+import store from '../vuex/store' // importe o armazém que acabamos de criar
+
+export default {
+  components: {
+    Display: Display,
+    Increment: Increment
+  },
+  store: store // Adicionando essa linha todos os componentes filhos saberão da existência do armazém
+}
+```
+
+> **Dica**: Com ES6 e Babel você pode utilizar da seguinte maneira:
+>
+>     components: {
+>       Display,
+>       Increment,
+>     },
+>     store
+
+### Passo 2: Crie as ações
+
+A ação é uma função que é chamada no componente. Funções de ação pode disparar atualizações no armazém ao disparar a mutação correta. Uma ação também pode fazer requisições HTTP e ler outros dados do armazém antes de disparar atualizações.
+
+Crie um novo arquivo em `vuex/actions.js` com uma simples função chamada `incrementCounter`
+
+```js
+// Uma ação irá receber um armazém como seu primeiro argumento
+// Já que estamos apenas interessados em disparar uma mutação
+// Nós podemos importar os dois parâmetros utilizando a habilidade de <i>destructuring</i> do ES6
+export const incrementCounter = function ({ dispatch, state }) {
+  dispatch('INCREMENT', 1)
+}
+```
+
+E vamos chamar a ação no nosso componente `components/Increment.vue`.
+
+```
+<template>
+  <div>
+    <button @click='increment'>Increment +1</button>
+  </div>
+</template>
+
+<script>
+import { incrementCounter } from '../vuex/actions'
+export default {
+  vuex: {
+    actions: {
+      increment: incrementCounter
+    }
+  }
+}
+</script>
+```
+
+Note algumas coisas interessantes que acabamos de adicionar:
+
+1. Nós temos um novo objeto chamado `vuex.actions` que inclui a nova ação
+2. Nós não especificamos qual armazém, objeto, estado e etc. O Vuex configura tudo por nós.
+3. Nós podemos chamar a ação chamando `this.increment()` em qualquer método.
+4. Nós podemos também chamar a ação utilizando passando de parâmetro a um evento `@click`, fazendo com que a ação `increment` atue como qualquer outro método Vue.
+5. A ação é chamada `incrementCounter`, mas nós podemos utilizar o nome que acharmos mais apropriado.
+
+### Passo 3: Configure o estado e a mutação
+
+No nosso arquivo `vuex/actions.js` nós disparamos uma mutação `INCREMENT` mas nós ainda não escrevemos como lidar com isso. Então vamos fazer isso agora.
+
+Edite o arquivo `vuex/store.js`
+
+```js
+const state = {
+  // Quando o aplicativo iniciar, o valor de count será 0
+  count: 0
+}
+
+const mutations = {
+  // Uma mutação recebe o estado atual como primeiro parâmetro
+  // Você pode fazer qualquer modificação dentro desse método
+  INCREMENT (state, amount) {
+    state.count = state.count + amount
+  }
+}
+```
+
+### Passo 4: Adicione o valor ao componente
+
+Crie um novo arquivo chamado `vuex/getters.js`
+
+```js
+// Esse getter é uma função que simplesmente retorna o valor do contador
+// Com o ES6 você pode escrever assim:
+// export const getCount = state => state.count
+
+export function getCount (state) {
+  return state.count
+}
+```
+
+Essa função retorna parte do objeto de estado que nos interessa - o valor atual do contador. Nós podemos utilizar esse getter dentro do componente.
+
+Edite o arquivo `components/Display.vue`
+
+```html
+<template>
+  <div>
+    <h3>Count is {{ counterValue }}</h3>
+  </div>
+</template>
+
+<script>
+import { getCount } from '../vuex/getters'
+export default {
+  vuex: {
+    getters: {
+      // note que você está passando uma função, e não o valor 'getCount()'
+      counterValue: getCount
+    }
+  }
+}
+</script>
+```
+
+Existe um novo objeto chamado `vuex.getters` que requisita a função `counterValue` para ser vinculada ao getter `getCount`. Nós escolhemos diferentes nomes para mostrar que você pode escolher o nome que fizer sentido ao contexto do seu componente, não necessariamente o nome do getter.
+
+Você deve estar se perguntando - por que nós escolhemos utilizar um getter ao invés de acessar diretamente o valor do estado. Esse conceito é mais uma boa prática, e é mais aplicável a uma aplicação mais complexa, e apresenta algumas vantagens:
+
+1. Nós podemos querer definir getters com valores computados (pense em totais, médias, etc.).
+2. Muitos componentes em um aplicativo mais complexo utilizam o mesmo getter.
+3. Se o valor for modificado, vamos dizer de `store.count` para `store.counter.value` você só precisa atualizar um getter ao invés de vários arquivos.
+
+Esses são apenas alguns dos benefícios de utilizar os getters.
+
+### Passo 5: Próximos Passos
+
+Se você rodar a aplicação, agora você verá ela funcionando como deveria.
+
+Para aumentar seu entendimento sobre o Vuex, você pode tentar implementar as seguintes modificações ao app, como um exercício.
+
+* Adicione um botão de decremento.
+* Instale o [Devtools do VueJS](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en) e explore as ferramentas do Vuex e observe as mutações sendo aplicadas.
+* Adicione um input do tipo texto em outro componente chamado `IncrementAmount` e entre com um valor para incrementar o contador. Isso pode ser um pouco diferente, já que os forms no Vuex funcionam de uma forma diferente. Leia o arquivo [Manipulações de Formulários](forms.md) para mais detalhes.
+

BIN
docs/pt/tutorial/result.png


BIN
docs/pt/tutorial/vuex_flow.png


BIN
docs/pt/vuex.png