Browse Source

docs(ptbr): add vuex translations for vuex 4 (#1880)

* Translated to Portuguese BR

Added config menu

* Translation fixes
periscuelo 4 năm trước cách đây
mục cha
commit
126ab7fa31

+ 57 - 0
docs/.vitepress/config.js

@@ -8,6 +8,11 @@ module.exports = {
       lang: 'en-US',
       title: 'Vuex',
       description: 'Centralized State Management for Vue.js'
+    },
+    '/ptbr/': {
+      lang: 'pt-BR',
+      title: 'Vuex',
+      description: 'Gerenciamento de Estado Centralizado para Vue.js'
     }
   },
 
@@ -80,6 +85,58 @@ module.exports = {
             ]
           }
         ]
+      },
+      '/ptbr/': {
+        nav: [
+          { text: 'Guia', link: '/ptbr/guide/' },
+          { text: 'Referência da API', link: '/ptbr/api/' },
+          { text: 'Notas de Lançamento', link: 'https://github.com/vuejs/vuex/releases' },
+          {
+            text: 'v4.x',
+            items: [
+              { text: 'v3.x', link: 'https://vuex.vuejs.org/ptbr/' }
+            ]
+          }
+        ],
+        sidebar: [
+          {
+            text: 'Introdução',
+            children: [
+              { text: 'O que é Vuex?', link: '/ptbr/' },
+              { text: 'Instalação', link: '/ptbr/installation' },
+              { text: 'Começando', link: '/ptbr/guide/' }
+            ]
+          },
+          {
+            text: 'Conceitos Básicos',
+            children: [
+              { text: 'Estado', link: '/ptbr/guide/state' },
+              { text: 'Getters', link: '/ptbr/guide/getters' },
+              { text: 'Mutações', link: '/ptbr/guide/mutations' },
+              { text: 'Ações', link: '/ptbr/guide/actions' },
+              { text: 'Módulos', link: '/ptbr/guide/modules' }
+            ]
+          },
+          {
+            text: 'Avançado',
+            children: [
+              { text: 'Estrutura da Aplicação', link: '/ptbr/guide/structure' },
+              { text: 'Composition API', link: '/ptbr/guide/composition-api' },
+              { text: 'Plugins', link: '/ptbr/guide/plugins' },
+              { text: 'Modo Strict', link: '/ptbr/guide/strict' },
+              { text: 'Manipulação de Formulários', link: '/ptbr/guide/forms' },
+              { text: 'Testando', link: '/ptbr/guide/testing' },
+              { text: 'Hot Reloading', link: '/ptbr/guide/hot-reload' },
+              { text: 'Suporte ao TypeScript', link: '/ptbr/guide/typescript-support' },
+            ]
+          },
+          {
+            text: 'Guia de Migração',
+            children: [
+              { text: 'Migrando do 3.x para 4.0', link: '/ptbr/guide/migrating-to-4-0-from-3-x' }
+            ]
+          }
+        ]
       }
     }
   }

+ 398 - 0
docs/ptbr/api/index.md

@@ -0,0 +1,398 @@
+---
+sidebar: auto
+---
+
+# Referência da API
+
+## Store
+
+### createStore
+
+- `createStore<S>(options: StoreOptions<S>): Store<S>`
+
+  Cria um novo _store_.
+
+  ```js
+  import { createStore } from 'vuex'
+
+  const store = createStore({ ...options })
+  ```
+
+## Opções do Construtor Store
+
+### state (estado)
+
+- type: `Object | Function`
+
+  O objeto raiz de estado para o _store_ Vuex. [Detalhes](../guide/state.md)
+
+  Se você passar uma função que retorna um objeto, o objeto retornado é usado como o estado raiz. Isso é útil quando você deseja reutilizar o objeto de estado, especialmente para reutilização de módulos. [Detalhes](../guide/modules.md#reutilizacao-do-modulo)
+
+### mutations (mutações)
+
+- type: `{ [type: string]: Function }`
+
+  Registra mutações no _store_. A função do manipulador sempre recebe _state_ como o 1º argumento (será o estado local do módulo se definido em um módulo) e receberá um 2º argumento _payload_ se houver um.
+
+  [Detalhes](../guide/mutations.md)
+
+### actions (ações)
+
+- type: `{ [type: string]: Function }`
+
+  Registra ações no _store_. A função do manipulador recebe um objeto _context_ que expõe as seguintes propriedades:
+
+  ```js
+  {
+    state,      // o mesmo que `store.state`, ou estado local se estiver em módulos
+    rootState,  // o mesmo que `store.state`, apenas em módulos
+    commit,     // o mesmo que `store.commit`
+    dispatch,   // o mesmo que `store.dispatch`
+    getters,    // o mesmo que `store.getters`, ou getters locais se estiver em módulos
+    rootGetters // o mesmo que `store.getters`, apenas em módulos
+  }
+  ```
+
+  E também recebe um 2º argumento _payload_ se houver um.
+
+  [Detalhes](../guide/actions.md)
+
+### getters
+
+- type: `{ [key: string]: Function }`
+
+  Registra os _getters_ no _store_. A função _getter_ recebe os seguintes argumentos:
+
+  ```
+  state,     // será estado local do módulo se definido em um módulo.
+  getters    // o mesmo que store.getters
+  ```
+
+  Especificamente quando definido em um módulo
+
+  ```
+  state,       // será estado local do módulo se definido em um módulo.
+  getters,     // módulo de getters locais do módulo atual.
+  rootState,   // estado global
+  rootGetters  // todos os getters
+  ```
+
+  Os _getters_ registrados estão expostos em `store.getters`.
+
+  [Detalhes](../guide/getters.md)
+
+### modules (módulos)
+
+- type: `Object`
+
+  Um objeto contendo sub módulos a serem incorporados no _store_, de forma que:
+
+  ```js
+  {
+    key: {
+      state,
+      namespaced?,
+      mutations?,
+      actions?,
+      getters?,
+      modules?
+    },
+    ...
+  }
+  ```
+
+  Cada módulo pode conter _state_ e _mutations_ semelhantes às opções raiz. O estado de um módulo será anexado ao estado da raiz do _store_ usando a chave do módulo. As mutações e _getters_ de um módulo receberão apenas o estado local do módulo como o 1º argumento em vez do estado da raiz, e as ações do módulo _context.state_ também apontarão para o estado local.
+
+  [Detalhes](../guide/modules.md)
+
+### plugins
+
+- type: `Array<Function>`
+
+  Um _Array_ de funções de plug-in a serem aplicadas no _store_. O plug-in simplesmente recebe o _store_ como o único argumento e pode ouvir mutações (para persistência de dados de saída, registro ou depuração) ou despachar mutações (para dados de entrada, por exemplo, _websockets_ ou _observables_).
+
+  [Detalhes](../guide/plugins.md)
+
+### strict
+
+- type: `boolean`
+- default: `false`
+
+  Força o _store_ Vuex a rodar mo modo estrito. No modo estrito, qualquer mutação ao estado do Vuex fora dos manipuladores de mutação acusará um erro.
+
+  [Detalhes](../guide/strict.md)
+
+### devtools
+
+- type: `boolean`
+
+  Ative ou desative o _devtools_ para uma determinada instância Vuex. Passar `false` à instância diz ao _store_ Vuex para não se integrar ao _devtools_. Bem útil quando se tem vários _stores_ em uma _single_ _page_.
+
+  ```js
+  {
+    devtools: false
+  }
+  ```
+
+## Propriedades da Instância Store
+
+### state (estado)
+
+- type: `Object`
+
+  O estado raiz. Apenas leitura.
+
+### getters
+
+- type: `Object`
+
+  Expõe os _getters_ registrados. Apenas leitura.
+
+## Métodos da Instância Store
+
+### commit
+
+-  `commit(type: string, payload?: any, options?: Object)`
+-  `commit(mutation: Object, options?: Object)`
+
+  Confirma (ou faz um _Commit_ de) uma mutação. _options_ pode ter `root: true` que permite confirmar mutações da raiz em [módulos namespaced](../guide/modules.md#namespacing). [Detalhes](../guide/mutations.md)
+
+### dispatch
+
+-  `dispatch(type: string, payload?: any, options?: Object): Promise<any>`
+-  `dispatch(action: Object, options?: Object): Promise<any>`
+
+  Despacha uma ação. _options_ pode ter `root: true` que permite despachar ações para raiz em [módulos namespaced](../guide/modules.md#namespacing). Retorna um _Promise_ que resolve todos os manipuladores de ação acionados. [Detalhes](../guide/actions.md)
+
+### replaceState
+
+-  `replaceState(state: Object)`
+
+  Substitue o estado da raiz do _store_. Use isso apenas para fins de _hydration_ / _time-travel_.
+
+### watch
+
+-  `watch(fn: Function, callback: Function, options?: Object): Function`
+
+  Visualiza de forma reativa um valor de retorno de `fn`, e chama o _callback_ para o retorno de chamada quando o valor for alterado. O `fn` recebe o estado do _store_ como o 1º argumento, e os _getters_ como o 2º argumento. Aceita um objeto de opções opcional que leva as mesmas opções que o [método vm.$watch do Vue](https://vuejs.org/v2/api/#vm-watch).
+
+  Para parar um _watch_, chame a função _unwatch_ retornada.
+
+### subscribe
+
+-  `subscribe(handler: Function, options?: Object): Function`
+
+  Assinatura para as mutações do _store_. O `manipulador` é chamado após cada mutação e recebe o descritor da mutação e o estado pós-mutação como argumentos:
+
+  ```js
+  const unsubscribe = store.subscribe((mutation, state) => {
+    console.log(mutation.type)
+    console.log(mutation.payload)
+  })
+
+  // you may call unsubscribe to stop the subscription
+  unsubscribe()
+  ```
+
+  Por padrão, o novo manipulador é adicionado ao final da cadeia, então ele será executado após outros manipuladores que foram adicionados antes. Isso pode ser sobrescrito adicionando `prepend: true` a _options_, que irá adicionar o manipulador ao início da cadeia.
+
+  ```js
+  store.subscribe(handler, { prepend: true })
+  ```
+
+  O método _subscribe_ retornará uma função _unsubscribe_, que deve ser chamada quando a assinatura não for mais necessária. Por exemplo, você pode assinar um Módulo Vuex e cancelar a assinatura ao cancelar o registro do módulo. Ou você pode chamar _subscribe_ de dentro de um componente Vue e então destruir o componente mais tarde. Nesses casos, você deve se lembrar de cancelar a assinatura manualmente.
+
+  Mais comumente usado em plugins. [Detalhes](../guide/plugins.md)
+
+### subscribeAction
+
+-  `subscribeAction(handler: Function, options?: Object): Function`
+
+  Assinatura para as ações do _store_. O `manipulador` é chamado para cada ação despachada e recebe o descritor da ação e o estado de armazenamento atual como argumentos.
+  O método _subscribe_ retornará uma função _unsubscribe_, que deve ser chamada quando a assinatura não for mais necessária. Por exemplo, ao cancelar o registro de um módulo Vuex ou antes de destruir um componente Vue.
+
+  ```js
+  const unsubscribe = store.subscribeAction((action, state) => {
+    console.log(action.type)
+    console.log(action.payload)
+  })
+
+  // you may call unsubscribe to stop the subscription
+  unsubscribe()
+  ```
+
+  Por padrão, o novo manipulador é adicionado ao final da cadeia, então ele será executado após outros manipuladores que foram adicionados antes. Isso pode ser sobrescrito adicionando `prepend: true` a _options_, que irá adicionar o manipulador ao início da cadeia.
+
+  ```js
+  store.subscribeAction(handler, { prepend: true })
+  ```
+
+  O método _subscribeAction_ retornará uma função _unsubscribe_, que deve ser chamada quando a assinatura não for mais necessária. Por exemplo, você pode assinar um Módulo Vuex e cancelar a assinatura ao cancelar o registro do módulo. Ou você pode chamar _subscribeAction_ de dentro de um componente Vue e então destruir o componente mais tarde. Nesses casos, você deve se lembrar de cancelar a assinatura manualmente.
+
+  _subscribeAction_ também pode especificar se a função manipuladora da assinatura deve ser chamada *antes* ou *depois* de um despacho de ação (o comportamento padrão é *antes*):
+
+  ```js
+  store.subscribeAction({
+    before: (action, state) => {
+      console.log(`before action ${action.type}`)
+    },
+    after: (action, state) => {
+      console.log(`after action ${action.type}`)
+    }
+  })
+  ```
+
+  _subscribeAction_ também pode especificar uma função manipuladora _error_ para capturar um erro lançado quando uma ação é despachada. A função receberá um objeto _error_ como 3º argumento.
+
+  ```js
+  store.subscribeAction({
+    error: (action, state, error) => {
+      console.log(`error action ${action.type}`)
+      console.error(error)
+    }
+  })
+  ```
+
+  O método _subscribeAction_ é mais comumente usado em plugins. [Detalhes](../guide/plugins.md)
+
+### registerModule
+
+-  `registerModule(path: string | Array<string>, module: Module, options?: Object)`
+
+  Registra um módulo dinâmico. [Detalhes](../guide/modules.md#registro-de-modulo-dinamico)
+
+  _options_ podem ter `preserveState: true` que permite preservar o estado anterior. Bem útil quando fazemos renderização do lado do servidor (_server-side-rendering_).
+
+### unregisterModule
+
+-  `unregisterModule(path: string | Array<string>)`
+
+  Cancela o registro de um módulo dinâmico. [Detalhes](../guide/modules.md#registro-de-modulo-dinamico)
+
+### hasModule
+
+- `hasModule(path: string | Array<string>): boolean`
+
+  Verifica se o módulo com o nome fornecido já foi registrado. [Detalhes](../guide/modules.md#registro-de-modulo-dinamico)
+
+### hotUpdate
+
+-  `hotUpdate(newOptions: Object)`
+
+  Faz _hot_ _swap_ de novas ações e mutações [Detalhes](../guide/hot-reload.md)
+
+## Métodos Auxiliares de Vinculação aos Componentes
+
+### mapState
+
+-  `mapState(namespace?: string, map: Array<string> | Object<string | function>): Object`
+
+  Cria dados computados do componente que retornam a subárvore do _store_ Vuex. [Detalhes](../guide/state.md#o-auxiliar-mapstate)
+
+  O 1º argumento pode ser opcionalmente uma _String_ com _namespace_. [Detalhes](../guide/modules.md#usando-metodos-auxiliares-com-namespace)
+
+  O segundo objeto que compõem os argumentos pode ser uma função. `function(state: any)`
+
+### mapGetters
+
+-  `mapGetters(namespace?: string, map: Array<string> | Object<string>): Object`
+
+  Cria dados computados do componente que retornam o valor calculado de um _getter_. [Detalhes](../guide/getters.md#o-auxiliar-mapgetters)
+
+  O 1º argumento pode ser opcionalmente uma _String_ com _namespace_. [Detalhes](../guide/modules.md#usando-metodos-auxiliares-com-namespace)
+
+### mapActions
+
+-  `mapActions(namespace?: string, map: Array<string> | Object<string | function>): Object`
+
+  Cria opções de métodos nos componentes que despacham uma ação. [Detalhes](../guide/actions.md#despachando-acoes-em-componentes)
+
+  O 1º argumento pode ser opcionalmente uma _String_ com _namespace_. [Detalhes](../guide/modules.md#usando-metodos-auxiliares-com-namespace)
+
+  O segundo objeto que compõem os argumentos pode ser uma função. `function(dispatch: function, ...args: any[])`
+
+### mapMutations
+
+-  `mapMutations(namespace?: string, map: Array<string> | Object<string | function>): Object`
+
+  Cria opções de métodos nos componentes que confirmam (ou fazem um _commit_ de) uma mutação. [Detalhes](../guide/mutations.md#confirmando-ou-fazendo-commits-de-mutacoes-em-componentes)
+
+  O 1º argumento pode ser opcionalmente uma _String_ com _namespace_. [Detalhes](../guide/modules.md#usando-metodos-auxiliares-com-namespace)
+
+  O segundo objeto que compõem os argumentos pode ser uma função. `function(commit: function, ...args: any[])`
+
+### createNamespacedHelpers
+
+-  `createNamespacedHelpers(namespace: string): Object`
+
+  Cria métodos auxiliares de componentes vinculados por um nome. O objeto retornado conterá `mapState`, `mapGetters`, `mapActions` e `mapMutations`, que estão vinculados ao _namespace_ fornecido. [Detalhes](../guide/modules.md#usando-metodos-auxiliares-com-namespace)
+
+## Funções de Composição
+
+### useStore
+
+- `useStore<S = any>(injectKey?: InjectionKey<Store<S>> | string): Store<S>;`
+
+  Busca o _store_ injetado quando chamado dentro do gatilho (ou _hook_) _setup_. Ao usar a API de composição, você pode recuperar o _store_ chamando este método.
+
+  ```js
+  import { useStore } from 'vuex'
+
+  export default {
+    setup () {
+      const store = useStore()
+    }
+  }
+  ```
+
+  Os usuários do TypeScript podem usar uma _injection_ _key_ para recuperar um _store_ tipado. Para que isso funcione, você deve definir a _injection_ _key_ e passá-la junto com o _store_ ao instalar a instância do _store_ na aplicação Vue.
+
+  Primeiro, declare a _injection_ _key_ usando a interface `InjectionKey` do Vue.
+
+  ```ts
+  // store.ts
+  import { InjectionKey } from 'vue'
+  import { createStore, Store } from 'vuex'
+
+  export interface State {
+    count: number
+  }
+
+  export const key: InjectionKey<Store<State>> = Symbol()
+
+  export const store = createStore<State>({
+    state: {
+      count: 0
+    }
+  })
+  ```
+
+  Então, passe a _key_ definida como o 2º argumento para o método `app.use`.
+
+  ```ts
+  // main.ts
+  import { createApp } from 'vue'
+  import { store, key } from './store'
+
+  const app = createApp({ ... })
+
+  app.use(store, key)
+
+  app.mount('#app')
+  ```
+
+  Finalmente, você pode passar a _key_ para o método _useStore_ para recuperar a instância tipada do _store_.
+
+  ```ts
+  // no componente vue
+  import { useStore } from 'vuex'
+  import { key } from './store'
+
+  export default {
+    setup () {
+      const store = useStore(key)
+
+      store.state.count // tipado como número
+    }
+  }
+  ```

+ 180 - 0
docs/ptbr/guide/actions.md

@@ -0,0 +1,180 @@
+# Actions
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/c6ggR3cG" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+As ações são semelhantes às mutações, as diferenças são as seguintes:
+
+- Em vez de mudar o estado, as ações confirmam (ou fazem _commit_ de) mutações.
+- As ações podem conter operações assíncronas arbitrárias.
+
+Vamos registrar uma ação simples:
+
+``` js
+const store = createStore({
+  state: {
+    count: 0
+  },
+  mutations: {
+    increment (state) {
+      state.count++
+    }
+  },
+  actions: {
+    increment (context) {
+      context.commit('increment')
+    }
+  }
+})
+```
+
+As funções manipuladoras de ação recebem um objeto _context_ que expõe o mesmo conjunto de métodos/propriedades na instância do _store_, para que você possa chamar `context.commit` para confirmar uma mutação ou acessar o estado e os _getters_ através do `context.state` e do `context.getters`. Podemos até chamar outras ações com `context.dispatch`. Veremos por que esse objeto _context_ não é a própria instância do _store_ quando apresentarmos [Módulos](modules.md) mais tarde.
+
+Na prática, muitas vezes usamos ES2015 [desestruturação de argumentos](https://github.com/lukehoban/es6features#destructuring) para simplificar um pouco o código (especialmente quando precisamos usar _commit_ várias vezes):
+
+``` js
+actions: {
+  increment ({ commit }) {
+    commit('increment')
+  }
+}
+```
+
+## Despachando Ações
+
+As ações são disparadas com o método `store.dispatch`:
+
+``` js
+store.dispatch('increment')
+```
+
+Isso pode parecer óbvio à primeira vista: se quisermos incrementar a contagem, por que não chamamos `store.commit('increment')` diretamente? Você se lembra que **as mutações devem ser síncronas**? As ações não. Podemos executar operações **assíncronas** dentro de uma ação:
+
+``` js
+actions: {
+  incrementAsync ({ commit }) {
+    setTimeout(() => {
+      commit('increment')
+    }, 1000)
+  }
+}
+```
+
+As ações suportam o mesmo formato de _payload_ e despacho estilo-objeto:
+
+``` js
+// despacho com payload
+store.dispatch('incrementAsync', {
+  amount: 10
+})
+
+// despacho com objeto
+store.dispatch({
+  type: 'incrementAsync',
+  amount: 10
+})
+```
+
+Um exemplo mais prático de ações reais seria uma ação para fazer _checkout_ de um carrinho de compras, que envolve **chamar uma API assíncrona** e **confirmar múltiplas mutações**:
+
+``` js
+actions: {
+  checkout ({ commit, state }, products) {
+    // salva os itens que estão no carrinho
+    const savedCartItems = [...state.cart.added]
+    // enviar solicitação de checkout e com otimismo
+    // limpa o carrinho
+    commit(types.CHECKOUT_REQUEST)
+    // a API da loja aceita um callback de sucesso e um callback de falha
+    shop.buyProducts(
+      products,
+      // callback em caso de sucesso
+      () => commit(types.CHECKOUT_SUCCESS),
+      // callback em caso de falha
+      () => commit(types.CHECKOUT_FAILURE, savedCartItems)
+    )
+  }
+}
+```
+
+Observe que estamos realizando um fluxo de operações assíncronas, e gravando os efeitos colaterais (mutações de estado) da ação confirmando-os (ou fazendo _commit_ deles).
+
+## Despachando Ações em Componentes
+
+Você pode despachar ações em componentes com `this.$store.dispatch('xxx')`, ou usar o auxiliar _mapActions_ que mapeia métodos do componente para chamadas do `store.dispatch` (esta ação requer a injeção do _store_ na instância raiz):
+
+``` js
+import { mapActions } from 'vuex'
+
+export default {
+  // ...
+  methods: {
+    ...mapActions([
+      'increment', // mapeia `this.increment()` para `this.$store.dispatch('increment')`
+
+      // `mapActions` também suporta payloads:
+      'incrementBy' // mapeia `this.incrementBy(amount)` para `this.$store.dispatch('incrementBy', amount)`
+    ]),
+    ...mapActions({
+      add: 'increment' // mapeia `this.add()` para `this.$store.dispatch('increment')`
+    })
+  }
+}
+```
+
+## Composição de Ações
+
+As ações geralmente são assíncronas, então como sabemos quando uma ação é realizada? E mais importante, como podemos compor ações múltiplas em conjunto para lidar com fluxos assíncronos mais complexos?
+
+A primeira coisa a saber é que o `store.dispatch` pode manipular a _Promise_ retornada pela função manipuladora de ação acionada que também retorna _Promise_:
+
+``` js
+actions: {
+  actionA ({ commit }) {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        commit('someMutation')
+        resolve()
+      }, 1000)
+    })
+  }
+}
+```
+
+Agora você pode fazer:
+
+``` js
+store.dispatch('actionA').then(() => {
+  // ...
+})
+```
+
+E também em outra ação:
+
+``` js
+actions: {
+  // ...
+  actionB ({ dispatch, commit }) {
+    return dispatch('actionA').then(() => {
+      commit('someOtherMutation')
+    })
+  }
+}
+```
+
+Finalmente, se fizermos uso de [async / await](https://tc39.github.io/ecmascript-asyncawait/), podemos compor nossas ações desta maneira:
+
+``` js
+// assumindo que `getData()` e `getOtherData()` retornam Promises
+
+actions: {
+  async actionA ({ commit }) {
+    commit('gotData', await getData())
+  },
+  async actionB ({ dispatch, commit }) {
+    await dispatch('actionA') // espera que `actionA` termine
+    commit('gotOtherData', await getOtherData())
+  }
+}
+```
+
+> É possível para um `store.dispatch` disparar várias funções manipuladoras de ação em diferentes módulos. Neste caso, o valor retornado será uma _Promise_ que se resolve quando todas as outras funções manipuladoras disparadas forem resolvidas.

+ 62 - 0
docs/ptbr/guide/composition-api.md

@@ -0,0 +1,62 @@
+# API de Composição (ou Composition API)
+
+Para acessar o _store_ dentro do gatilho (ou _hook_) `setup`, você pode chamar a função `useStore`. Isso é o equivalente a recuperar `this.$store` dentro de um componente usando a API de Opções (ou _Option_ API).
+
+```js
+import { useStore } from 'vuex'
+
+export default {
+  setup () {
+    const store = useStore()
+  }
+}
+```
+
+## Acessando Estado e Getters
+
+Para acessar o estado e os _getters_, você deve criar referências `computed` para reter a reatividade. Isso é o equivalente a criar dados computados usando a API de Opções (ou _Option_ API).
+
+```js
+import { computed } from 'vue'
+import { useStore } from 'vuex'
+
+export default {
+  setup () {
+    const store = useStore()
+
+    return {
+      // acessar um estado em uma função de dados computados
+      count: computed(() => store.state.count),
+
+      // acessar um getter em uma função de dados computados
+      double: computed(() => store.getters.double)
+    }
+  }
+}
+```
+
+## Acessando Mutações e Ações
+
+Ao acessar mutações e ações, você pode simplesmente fornecer as funções `commit` e `dispatch` dentro do gatilho (ou _hook_) `setup`.
+
+```js
+import { useStore } from 'vuex'
+
+export default {
+  setup () {
+    const store = useStore()
+
+    return {
+      // acessa uma mutação
+      increment: () => store.commit('increment'),
+
+      // acessa uma ação
+      asyncIncrement: () => store.dispatch('asyncIncrement')
+    }
+  }
+}
+```
+
+## Exemplos
+
+Confira o [exemplo da API de Composição](https://github.com/vuejs/vuex/tree/4.0/examples/composition) para ver exemplos de aplicações que utilizam Vuex e a API de Composição (ou _Composition_ API) do Vue.

+ 65 - 0
docs/ptbr/guide/forms.md

@@ -0,0 +1,65 @@
+# Manipulação de Formulários
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/cqKRgEC9" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+Ao usar o Vuex no modo estrito, pode ser um pouco complicado usar `v-model` em um pedaço do estado que pertence ao Vuex:
+
+``` html
+<input v-model="obj.message">
+```
+
+Assumindo que `obj` é um dado computado que retorna um Objeto do _store_, o `v-model` aqui tentará alterar diretamente o `obj.message` quando o usuário digitar alguma coisa. No modo estrito, isso resultará em um erro porque a mutação não é executada dentro de uma função explícita manipuladora de mutação do Vuex.
+
+
+O "modo Vuex" de lidar com isso é vinculando o valor do(s) `<input>`'s e chamar uma ação no evento _input_ ou _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)
+  }
+}
+```
+
+E aqui está a função manipuladora de mutação:
+
+``` js
+// ...
+mutations: {
+  updateMessage (state, message) {
+    state.obj.message = message
+  }
+}
+```
+
+## Dados Computados Bidirecionais (Two-way)
+
+É certo que o código acima é um pouco mais verboso do que o `v-model` + estado local, e também perdemos alguns dos recursos úteis do `v-model`. Uma abordagem alternativa é usar um dado computado bidirecional com um _setter_:
+
+``` html
+<input v-model="message">
+```
+
+``` js
+// ...
+computed: {
+  message: {
+    get () {
+      return this.$store.state.obj.message
+    },
+    set (value) {
+      this.$store.commit('updateMessage', value)
+    }
+  }
+}
+```

+ 118 - 0
docs/ptbr/guide/getters.md

@@ -0,0 +1,118 @@
+# Getters
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/c2Be7TB" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+Às vezes, talvez precisemos calcular o estado derivado com base no estado do _store_, por exemplo, filtrar através de uma lista de itens e contá-los:
+
+``` js
+computed: {
+  doneTodosCount () {
+    return this.$store.state.todos.filter(todo => todo.done).length
+  }
+}
+```
+
+Se mais do que um componente precisa fazer uso disso, temos que duplicar a função, ou extraí-lo em um auxiliar compartilhado e importá-lo em vários lugares - ambos são menos do que o ideal.
+
+O Vuex nos permite definir _getters_ no _store_. Você pode pensar neles como dados computados para os _stores_. Como os dados computados, o resultado de um _getter_ é armazenado em _cache_ com base em suas dependências e só será reavaliado quando algumas de suas dependências forem alteradas.
+
+Os _getters_ receberão o estado como 1º argumento:
+
+``` js
+const store = createStore({
+  state: {
+    todos: [
+      { id: 1, text: '...', done: true },
+      { id: 2, text: '...', done: false }
+    ]
+  },
+  getters: {
+    doneTodos (state) {
+      return state.todos.filter(todo => todo.done)
+    }
+  }
+})
+```
+
+## Acesso Estilo-Propriedade
+
+Os _getters_ serão expostos no objeto `store.getters` e você acessa valores como propriedades:
+
+``` js
+store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
+```
+
+Os _getters_ também recebem outros _getters_ como o 2º argumento:
+
+``` js
+getters: {
+  // ...
+  doneTodosCount (state, getters) {
+    return getters.doneTodos.length
+  }
+}
+```
+
+``` js
+store.getters.doneTodosCount // -> 1
+```
+
+Agora podemos usar facilmente isso dentro de qualquer componente:
+
+``` js
+computed: {
+  doneTodosCount () {
+    return this.$store.getters.doneTodosCount
+  }
+}
+```
+
+Observe que os _getters_ acessados ​​como propriedades são armazenados em _cache_ como parte do sistema de reatividade do Vue.
+
+## Acesso Estilo-Método
+
+Você também pode passar argumentos para os _getters_ retornando uma função. Isso é particularmente útil quando você deseja consultar um _Array_ no _store_:
+
+```js
+getters: {
+  // ...
+  getTodoById: (state) => (id) => {
+    return state.todos.find(todo => todo.id === id)
+  }
+}
+```
+
+``` js
+store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
+```
+
+Observe que os _getters_ acessados ​​via métodos serão executados toda vez que você os chamar, e o resultado não será armazenado em _cache_.
+
+## O Auxiliar `mapGetters`
+
+O auxiliar _mapGetters_ simplesmente mapeia os _getters_ do _store_ para os dados computados locais:
+
+``` js
+import { mapGetters } from 'vuex'
+
+export default {
+  // ...
+  computed: {
+    // mistura os getters nos dados computatos com o operador spread
+    ...mapGetters([
+      'doneTodosCount',
+      'anotherGetter',
+      // ...
+    ])
+  }
+}
+```
+
+Se você deseja mapear um _getter_ com um nome diferente, use um objeto:
+
+``` js
+...mapGetters({
+  // mapeia `this.doneCount` para `this.$store.getters.doneTodosCount`
+  doneCount: 'doneTodosCount'
+})
+```

+ 85 - 0
docs/ptbr/guide/hot-reload.md

@@ -0,0 +1,85 @@
+# Hot Reloading (Recarregamento Rápido)
+
+O Vuex suporta _hot-reloading_ de mutações, módulos, ações e _getters_ durante o desenvolvimento, utilizando o _webpack_ [Hot Module Replacement API](https://webpack.js.org/guides/hot-module-replacement/). Você também pode usá-lo no Browserify com o _plugin_ [browserify-hmr](https://github.com/AgentME/browserify-hmr/).
+
+Para mutações e módulos, você precisa usar o método da API `store.hotUpdate()`:
+
+``` js
+// store.js
+import { createStore } from 'vuex'
+import mutations from './mutations'
+import moduleA from './modules/a'
+
+const state = { ... }
+
+const store = createStore({
+  state,
+  mutations,
+  modules: {
+    a: moduleA
+  }
+})
+
+if (module.hot) {
+  // aceita ações e mutações como 'hot modules'
+  module.hot.accept(['./mutations', './modules/a'], () => {
+    // requer os módulos atualizados
+    // tem que adicionar .default aqui devido à saída do módulo babel 6
+    const newMutations = require('./mutations').default
+    const newModuleA = require('./modules/a').default
+    // troca nas novas ações e mutações
+    store.hotUpdate({
+      mutations: newMutations,
+      modules: {
+        a: newModuleA
+      }
+    })
+  })
+}
+```
+
+Confira o [counter-hot example](https://github.com/vuejs/vuex/tree/dev/examples/counter-hot) para brincar com o _hot-reload_.
+
+## Módulo dinâmico de hot reloading
+
+Se você usa exclusivamente módulos, você pode usar `require.context` para carregar e recarregar todos os módulos dinamicamente.
+
+```js
+// store.js
+import { createStore } from 'vuex'
+
+// Carrega todos os módulos.
+function loadModules() {
+  const context = require.context("./modules", false, /([a-z_]+)\.js$/i)
+
+  const modules = context
+    .keys()
+    .map((key) => ({ key, name: key.match(/([a-z_]+)\.js$/i)[1] }))
+    .reduce(
+      (modules, { key, name }) => ({
+        ...modules,
+        [name]: context(key).default
+      }),
+      {}
+    )
+
+  return { context, modules }
+}
+
+const { context, modules } = loadModules()
+
+const store = createStore({
+  modules
+})
+
+if (module.hot) {
+  // Hot reload sempre que qualquer módulo for alterado.
+  module.hot.accept(context.id, () => {
+    const { modules } = loadModules()
+
+    store.hotUpdate({
+      modules
+    })
+  })
+}
+```

+ 61 - 0
docs/ptbr/guide/index.md

@@ -0,0 +1,61 @@
+# Começando
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/cMPa2Uk" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+No centro de cada aplicação Vuex existe o **_store_**. Um "_store_" é basicamente um contêiner que mantém o **estado** da sua aplicação. Há duas coisas que tornam um _store_ Vuex diferente de um objeto global simples:
+
+1. Os _stores_ Vuex são reativos. Quando os componentes do Vue obtêm o estado dele, eles atualizarão de forma reativa e eficiente se o estado do _store_ mudar.
+
+2. Você não pode alterar diretamente os estados do _store_. A única maneira de mudar o estado de um _store_ é explicitamente **confirmando (ou fazendo _commit_ de) mutações**. Isso garante que cada mudança de estado deixe um registro rastreável, e permite ferramentas que nos ajudem a entender melhor nossas aplicações.
+
+## Um Store Bem Simples
+
+:::tip NOTE
+Vamos usar a sintaxe ES2015 para exemplos de código para o resto da documentação. Se você ainda não aprendeu como usá-la, [veja aqui](https://babeljs.io/docs/learn-es2015/)!
+:::
+
+Após [instalar](../installation.md)  o Vuex, vamos criar um _store_. É bem simples - basta fornecer um objeto de estado inicial, e algumas mutações:
+
+```js
+import { createApp } from 'vue'
+import { createStore } from 'vuex'
+
+// Cria uma nova instância do store.
+const store = createStore({
+  state () {
+    return {
+      count: 1
+    }
+  }
+})
+
+const app = createApp({ /* seu componente raiz */ })
+
+// Instale a instância do store como um plugin
+app.use(store)
+```
+
+Agora, você pode acessar o objeto de estado como `store.state` e acionar uma mudança de estado com o método `store.commit`:
+
+```js
+store.commit('increment')
+
+console.log(store.state.count) // -> 1
+```
+
+Em um componente Vue, você pode acessar o _store_ como `this.$store`. Agora podemos confirmar (ou fazer _commit_ de) uma mutação usando um método de componente:
+
+```js
+methods: {
+  increment() {
+    this.$store.commit('increment')
+    console.log(this.$store.state.count)
+  }
+}
+```
+
+Novamente, a razão pela qual estamos confirmando (ou fazendo _commit_ de) uma mutação em vez de mudar `store.state.count` diretamente, é porque queremos rastreá-la explicitamente. Esta convenção simples torna sua intenção mais explícita, para que você possa raciocinar melhor sobre as mudanças de estado em sua aplicação ao ler o código. Além disso, isso nos dá a oportunidade de implementar ferramentas que podem registrar cada mutação, capturar momentos do estado ou mesmo realizar depuração viajando pelo histórico de estado (_time travel_).
+
+Usar o estado do _store_ em um componente simplesmente envolve o retorno do estado dentro de um dado computado, porque o estado do _store_ é reativo. Acionar alterações simplesmente significa confirmar (ou fazer _commit_ de) mutações nos métodos dos componentes.
+
+A seguir, discutiremos cada conceito básico em detalhes muito mais sutis, começando com [Estado](state.md).

+ 117 - 0
docs/ptbr/guide/migrating-to-4-0-from-3-x.md

@@ -0,0 +1,117 @@
+# Migrando para versão 4.0 da versão 3.x
+
+Quase todas as APIs do Vuex 4 permaneceram inalteradas desde o Vuex 3. No entanto, ainda existem algumas mudanças importantes que você deve corrigir.
+
+- [Alterações Importantes](#alterações-importantes)
+  - [Processo de instalação](#processo-de-instalação)
+  - [Suporte ao TypeScript](#suporte-ao-typescript)
+  - [Os pacotes agora estão alinhados com Vue 3](#os-pacotes-agora-estão-alinhados-com-vue-3)
+  - [A função "createLogger" é exportada do módulo principal](#a-função-createLogger-é-exportada-do-módulo-principal)
+- [Novas Características](#novas-características)
+  - [Nova função de composição "useStore"](#nova-função-de-composição-useStore)
+
+## Alterações Importantes
+
+### Processo de instalação
+
+Para alinhar com o novo processo de inicialização do Vue 3, o processo de instalação do Vuex mudou. Para criar um novo _store_, os usuários agora são incentivados a usar a função createStore recém-introduzida.
+
+```js
+import { createStore } from 'vuex'
+
+export const store = createStore({
+  state () {
+    return {
+      count: 1
+    }
+  }
+})
+```
+
+Para instalar Vuex em uma instância Vue, passe o `store` em vez do Vuex.
+
+```js
+import { createApp } from 'vue'
+import { store } from './store'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(store)
+
+app.mount('#app')
+```
+
+:::tip NOTE
+Embora esta não seja tecnicamente uma alteração importante, você ainda pode usar a sintaxe `new Store(...)`, recomendamos esta abordagem para alinhar com Vue 3 e Vue Router Next.
+:::
+
+### Suporte ao TypeScript
+
+Vuex 4 remove suas tipagens globais para `this.$store` dentro de um componente Vue para resolver essa [issue #994](https://github.com/vuejs/vuex/issues/994). Quando usado com TypeScript, você deve declarar seu próprio _module_ _augmentation_.
+
+Coloque o seguinte código em seu projeto para permitir que `this.$store` seja tipado corretamente:
+
+```ts
+// vuex-shim.d.ts
+
+import { ComponentCustomProperties } from 'vue'
+import { Store } from 'vuex'
+
+declare module '@vue/runtime-core' {
+  // Declare seus próprios estados do store
+  interface State {
+    count: number
+  }
+
+  interface ComponentCustomProperties {
+    $store: Store<State>
+  }
+}
+```
+
+Você pode aprender mais na seção [Suporte ao TypeScript](./typescript-support).
+
+### Os pacotes agora estão alinhados com Vue 3
+
+Os seguintes pacotes são gerados para se alinhar aos pacotes Vue 3:
+
+- `vuex.global(.prod).js`
+  - Para uso direto com `<script src="...">` no navegador. Expõe o Vuex global.
+  - A distribuição (ou _build_) global é construída como IIFE, e não UMD, e destina-se apenas ao uso direto com `<script src="...">`.
+  - Contém branches chumbadas no código (ou _hard-coded_) de prod/dev e a compilação de prod é pré-minificada. Use os arquivos `.prod.js` para produção.
+- `vuex.esm-browser(.prod).js`
+  - Para uso com importações de módulo ES nativo (incluindo navegadores de suporte de módulo via `<script type="module">`.
+- `vuex.esm-bundler.js`
+  - Para uso com empacotadores como `webpack`, `rollup` e `parcel`.
+  - Deixa os branches de prod/dev com os guardas de tipo `process.env.NODE_ENV` (deve ser substituído pelo empacotador).
+  - Does not ship minified builds (to be done together with the rest of the code after bundling).
+  - Não envia distribuições (ou _builds_) minificados (para ser feito junto com o resto do código após o empacotamento).
+- `vuex.cjs.js`
+  - Para uso em renderização do lado do servidor (_server-side_ _rendering_) no Node.js com `require()`.
+
+### A função `createLogger` é exportada do módulo principal
+
+No Vuex 3, a função `createLogger` foi exportada de `vuex/dist/logger`, mas agora está incluída no pacote principal. A função deve ser importada diretamente do pacote `vuex`.
+
+```js
+import { createLogger } from 'vuex'
+```
+
+## Novas Características
+
+### Nova função de composição `useStore`
+
+Vuex 4 apresenta uma nova API para interagir com o _store_ na API de composição (ou _Composition_ API). Você pode usar a função de composição `useStore` para recuperar o _store_ dentro do gatilho (ou _hook_) `setup` do componente.
+
+```js
+import { useStore } from 'vuex'
+
+export default {
+  setup () {
+    const store = useStore()
+  }
+}
+```
+
+Você pode aprender mais na seção [API de Composição](./composition-api).

+ 341 - 0
docs/ptbr/guide/modules.md

@@ -0,0 +1,341 @@
+# Módulos
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/cqKK4psq" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+Devido ao uso de uma única árvore de estado, todos os estados da nossa aplicação estão contidos dentro de um grande objeto. No entanto, à medida que nossa aplicação cresce em escala, o _store_ pode ficar realmente inchado.
+
+Para ajudar com isso, o Vuex nos permite dividir nosso _store_ em **módulos**. Cada módulo pode conter seu próprio estado, mutações, ações, _getters_ e até módulos aninhados - o padrão se repete em todo o fluxo abaixo:
+
+```js
+const moduleA = {
+  state: () => ({ ... }),
+  mutations: { ... },
+  actions: { ... },
+  getters: { ... }
+}
+
+const moduleB = {
+  state: () => ({ ... }),
+  mutations: { ... },
+  actions: { ... }
+}
+
+const store = createStore({
+  modules: {
+    a: moduleA,
+    b: moduleB
+  }
+})
+
+store.state.a // -> `moduleA`'s state
+store.state.b // -> `moduleB`'s state
+```
+
+## Estado Local do Módulo
+
+Dentro das mutações e _getters_ de um módulo, o 1º argumento recebido será **o estado local do módulo**.
+
+```js
+const moduleA = {
+  state: () => ({
+    count: 0
+  }),
+  mutations: {
+    increment (state) {
+      // `state` é o estado local do módulo
+      state.count++
+    }
+  },
+  getters: {
+    doubleCount (state) {
+      return state.count * 2
+    }
+  }
+}
+```
+
+Da mesma forma, dentro das ações do módulo, `context.state` irá expor o estado local, e o estado raiz será exposto como `context.rootState`:
+
+```js
+const moduleA = {
+  // ...
+  actions: {
+    incrementIfOddOnRootSum ({ state, commit, rootState }) {
+      if ((state.count + rootState.count) % 2 === 1) {
+        commit('increment')
+      }
+    }
+  }
+}
+```
+
+Além disso, dentro do módulo _getters_, o estado raiz será exibido como seu 3º argumento:
+
+```js
+const moduleA = {
+  // ...
+  getters: {
+    sumWithRootCount (state, getters, rootState) {
+      return state.count + rootState.count
+    }
+  }
+}
+```
+
+## Namespacing
+
+Por padrão, ações, mutações e _getters_ dentro dos módulos ainda são registrados sob o **_namespace_ global** - isso permite que vários módulos reajam ao mesmo tipo de ação/mutação.
+
+Se você quer que seus módulos sejam mais independentes ou reutilizáveis, você pode usá-los com _namespaces_ através do `namespaced: true`. Quando o módulo é registrado, todos os _getters_, ações e mutações terão automaticamente o _namespace_ com base no caminho no qual o módulo está registrado. Por exemplo:
+
+```js
+const store = createStore({
+  modules: {
+    account: {
+      namespaced: true,
+
+      // recursos do módulo
+      state: () => ({ ... }), // o estado do módulo já está aninhado e não é afetado pela opção namespace
+      getters: {
+        isAdmin () { ... } // -> getters['account/isAdmin']
+      },
+      actions: {
+        login () { ... } // -> dispatch('account/login')
+      },
+      mutations: {
+        login () { ... } // -> commit('account/login')
+      },
+
+      // módulos aninhados
+      modules: {
+        // herda o namespace do módulo pai
+        myPage: {
+          state: () => ({ ... }),
+          getters: {
+            profile () { ... } // -> getters['account/profile']
+          }
+        },
+
+        // aninhar ainda mais o namespace
+        posts: {
+          namespaced: true,
+
+          state: () => ({ ... }),
+          getters: {
+            popular () { ... } // -> getters['account/posts/popular']
+          }
+        }
+      }
+    }
+  }
+})
+```
+
+Os _getters_ e as ações com _namespace_ receberão `getters`, `dispatch` e `commit` localizados. Em outras palavras, você pode usar os recursos do módulo sem escrever prefixo no mesmo módulo. Alternar entre com _namespace_ ou não, não afeta o código dentro do módulo.
+
+### Acessando Recursos Globais em Módulos com Namespaces
+
+Se você quiser usar estado global e _getters_, `rootState` e `rootGetters` são passados como o 3º e 4º argumentos para funções _getter_, e também expostos como propriedades no objeto `context` passado para funções de ação.
+
+Para despachar ações ou confirmar (ou fazer um _commit_ de) mutações no _namespace_ global, passe `{root: true}` como o 3º argumento para `dispatch` e `commit`.
+
+```js
+modules: {
+  foo: {
+    namespaced: true,
+
+    getters: {
+      // `getters` está localizado nos getters deste módulo
+      // você pode usar rootGetters como 4º argumento de getters
+      someGetter (state, getters, rootState, rootGetters) {
+        getters.someOtherGetter // -> 'foo/someOtherGetter'
+        rootGetters.someOtherGetter // -> 'someOtherGetter'
+        rootGetters['bar/someOtherGetter'] // -> 'bar/someOtherGetter'
+      },
+      someOtherGetter: state => { ... }
+    },
+
+    actions: {
+      // dispatch e commit também estão localizados para este módulo
+      // eles aceitarão a opção `root` para o dispatch/commit raiz
+      someAction ({ dispatch, commit, getters, rootGetters }) {
+        getters.someGetter // -> 'foo/someGetter'
+        rootGetters.someGetter // -> 'someGetter'
+        rootGetters['bar/someGetter'] // -> 'bar/someGetter'
+
+        dispatch('someOtherAction') // -> 'foo/someOtherAction'
+        dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
+
+        commit('someMutation') // -> 'foo/someMutation'
+        commit('someMutation', null, { root: true }) // -> 'someMutation'
+      },
+      someOtherAction (ctx, payload) { ... }
+    }
+  }
+}
+```
+
+### Registrar Ação Global em Módulos com Namespaces
+
+Se você quiser registrar ações globais em módulos com _namespaces_, você pode marcá-lo com `root: true` e colocar a definição de ação na função `handler`. Por exemplo:
+
+```js
+{
+  actions: {
+    someOtherAction ({dispatch}) {
+      dispatch('someAction')
+    }
+  },
+  modules: {
+    foo: {
+      namespaced: true,
+
+      actions: {
+        someAction: {
+          root: true,
+          handler (namespacedContext, payload) { ... } // -> 'someAction'
+        }
+      }
+    }
+  }
+}
+```
+
+### Vinculando Métodos Auxiliares com Namespace
+
+Ao vincular um módulo com _namespace_ aos componentes com os auxiliares `mapState`, `mapGetters`, `mapActions` e `mapMutations`, ele pode ficar um pouco verboso:
+
+```js
+computed: {
+  ...mapState({
+    a: state => state.some.nested.module.a,
+    b: state => state.some.nested.module.b
+  }),
+  ...mapGetters([
+    'some/nested/module/someGetter', // -> this['some/nested/module/someGetter']
+    'some/nested/module/someOtherGetter', // -> this['some/nested/module/someOtherGetter']
+  ])
+},
+methods: {
+  ...mapActions([
+    'some/nested/module/foo', // -> this['some/nested/module/foo']()
+    'some/nested/module/bar' // -> this['some/nested/module/bar']()
+  ])
+}
+```
+
+Nesses casos, você pode passar a _String_ do _namespace_ do módulo como o 1º argumento para os métodos auxiliares, de modo que todas as ligações sejam feitas usando esse módulo como o contexto. O acima pode ser simplificado para:
+
+```js
+computed: {
+  ...mapState('some/nested/module', {
+    a: state => state.a,
+    b: state => state.b
+  }),
+  ...mapGetters('some/nested/module', [
+    'someGetter', // -> this.someGetter
+    'someOtherGetter', // -> this.someOtherGetter
+  ])
+},
+methods: {
+  ...mapActions('some/nested/module', [
+    'foo', // -> this.foo()
+    'bar' // -> this.bar()
+  ])
+}
+```
+
+Além disso, você pode criar métodos auxiliares com _namespace_ usando `createNamespacedHelpers`. Ele retorna um objeto com novos métodos auxiliares dos componentes vinculados ao valor do _namespace_ fornecido:
+
+```js
+import { createNamespacedHelpers } from 'vuex'
+
+const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
+
+export default {
+  computed: {
+    // procura em `some/nested/module`
+    ...mapState({
+      a: state => state.a,
+      b: state => state.b
+    })
+  },
+  methods: {
+    // procura em `some/nested/module`
+    ...mapActions([
+      'foo',
+      'bar'
+    ])
+  }
+}
+```
+
+### Advertência para Desenvolvedores de Plug-ins
+
+Você pode se preocupar com _namespacing_ imprevisível para seus módulos ao criar um [plugin] (plugins.md) que fornece os módulos e permite que os usuários os adicionem a um _store_ Vuex. Seus módulos também terão _namespaces_ se os usuários do _plugin_ adicionarem seus módulos em um módulo com _namespace_. Para se adaptar a essa situação, pode ser necessário receber um valor de _namespace_ por meio das opções do seu _plugin_:
+
+```js
+// obtem valor do namespace via opção do plugin
+// e retorna a função plugin do Vuex
+export function createPlugin (options = {}) {
+  return function (store) {
+    // adiciona namespace aos tipos de módulos do plugin
+    const namespace = options.namespace || ''
+    store.dispatch(namespace + 'pluginAction')
+  }
+}
+```
+
+## Registro de Módulo Dinâmico
+
+Você pode registrar um módulo **após** o _store_ ser criado com o método `store.registerModule`:
+
+```js
+import { createStore } from 'vuex'
+
+const store = createStore({ /* options */ })
+
+// registra um módulo `myModule`
+store.registerModule('myModule', {
+  // ...
+})
+
+// registra um módulo aninhado `nested/myModule`
+store.registerModule(['nested', 'myModule'], {
+  // ...
+})
+```
+
+Os estados do módulo serão expostos como `store.state.myModule` e `store.state.nested.myModule`.
+
+O registro de módulo dinâmico possibilita que outros _plugins_ Vue aproveitem também o Vuex para gerenciamento de estado, anexando um módulo ao _store_ da aplicação. Por exemplo, a biblioteca [`vuex-router-sync`](https://github.com/vuejs/vuex-router-sync) integra o vue-router com o vuex gerenciando o estado da rota do aplicativo em um módulo conectado dinamicamente.
+
+Você também pode remover um módulo dinamicamente registrado com o `store.unregisterModule(moduleName)`. Note que você não pode remover módulos estáticos (declarados na criação do _store_) com este método.
+
+Observe que você pode verificar se o módulo já está registrado no _store_ ou não através do método `store.hasModule (moduleName)`.
+
+### Preservando o estado
+
+É bem provável que você queira preservar o estado anterior ao registrar um novo módulo, como preservar o estado de um aplicativo Renderizado no Lado do Servidor (_Server_ _Side_ _Rendered_). Você pode fazer isso com a opção `preserveState`:`store.registerModule('a', module, {preserveState: true})`
+
+Quando você define `preserveState: true`, o módulo é registrado, as ações, mutações e _getters_ são incluídos no _store_, mas o estado não. É assumido que estado da sua _store_ já contém um estado para aquele módulo e você não quer sobrescrevê-lo.
+
+## Reutilização do Módulo
+
+Às vezes, podemos precisar criar várias instâncias de um módulo, por exemplo:
+
+- Criando múltiplos _stores_ que usam o mesmo módulo (e.g. Para [evitar Singletons com informações do estado no SSR](https://ssr.vuejs.org/en/structure.html#avoid-stateful-singletons) quando a opção `runInNewContext` é `false` ou `'_once_'`);
+- Registrar o mesmo módulo várias vezes no mesmo _store_.
+
+Se usarmos um objeto simples para declarar o estado do módulo, esse objeto de estado será compartilhado por referência e causará poluição entre estados de _store_/módulo quando ele sofrer uma mutação.
+
+Este é exatamente o mesmo problema com `data` dentro dos componentes Vue. Então, a solução também é a mesma - use uma função para declarar o estado do módulo (suportado em 2.3.0+):
+
+```js
+const MyReusableModule = {
+  state: () => ({
+    foo: 'bar'
+  }),
+  // mutations, actions, getters...
+}
+```

+ 160 - 0
docs/ptbr/guide/mutations.md

@@ -0,0 +1,160 @@
+# Mutações
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/ckMZp4HN" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+A única maneira de realmente mudar de estado em um _store_ Vuex é por confirmar (ou fazer _commit_ de) uma mutação. As mutações do Vuex são muito semelhantes aos eventos: cada mutação tem uma _String_ **_type_** e um **_handler_**. Na função manipuladora (ou _handler_) é onde realizamos modificações de estado reais e ele receberá o estado como o 1º argumento:
+
+
+```js
+const store = createStore({
+  state: {
+    count: 1
+  },
+  mutations: {
+    increment (state) {
+      // muda o estado
+      state.count++
+    }
+  }
+})
+```
+
+Você não pode chamar diretamente uma função manipuladora de mutação. Pense nisso mais como registro de evento: "Quando uma mutação com o _type_ `increment` é acionada, chame este _handler_." Para invocar uma função manipuladora de mutação (_handler_), você precisa chamar `store.commit` com seu tipo (_type_):
+
+```js
+store.commit('increment')
+```
+
+## Confirmação (ou Commit) com Payload
+
+Você pode passar um argumento adicional para o `store.commit`, que é chamado de **_payload_** para a mutação:
+
+```js
+// ...
+mutations: {
+  increment (state, n) {
+    state.count += n
+  }
+}
+```
+
+```js
+store.commit('increment', 10)
+```
+
+Na maioria dos casos, o _payload_ deve ser um objeto para que possa conter vários campos, e a mutação gravada também será mais descritiva:
+
+```js
+// ...
+mutations: {
+  increment (state, payload) {
+    state.count += payload.amount
+  }
+}
+```
+
+```js
+store.commit('increment', {
+  amount: 10
+})
+```
+
+## Confirmação (ou Commit) Estilo-Objeto
+
+Uma maneira alternativa de confirmar (ou fazer um _commit_ de) uma mutação é usando diretamente um objeto que tenha uma propriedade `type`:
+
+```js
+store.commit({
+  type: 'increment',
+  amount: 10
+})
+```
+
+Ao usar a Confirmação Estilo-Objeto, o objeto inteiro será passado como o _payload_ para os manipuladores de mutação, portanto, a função manipuladora permanecerá a mesma:
+
+```js
+mutations: {
+  increment (state, payload) {
+    state.count += payload.amount
+  }
+}
+```
+
+## Usando Constantes para Declarar os Tipos de Mutação
+
+É um padrão comumente visto usar constantes para declarar tipos de mutação em várias implementações do Flux. Isso permite que o código aproveite as ferramentas como os _linters_, e colocar todas as constantes em um único arquivo permite que seus colaboradores tenham uma visão geral das mutações possíveis em toda a aplicação:
+
+```js
+// mutation-types.js
+export const SOME_MUTATION = 'SOME_MUTATION'
+```
+
+```js
+// store.js
+import { createStore } from 'vuex'
+import { SOME_MUTATION } from './mutation-types'
+
+const store = createStore({
+  state: { ... },
+  mutations: {
+    // podemos usar o recurso de nome do dado computado do ES2015
+    // para usar uma constante como o nome da função
+    [SOME_MUTATION] (state) {
+      // muda o estado
+    }
+  }
+})
+```
+
+Se usar constantes é em grande parte uma preferência - pode ser útil em grandes projetos com muitos desenvolvedores, mas é totalmente opcional se você não gostar deles.
+
+## Mutações Devem Ser Síncronas
+
+Uma regra importante a lembrar é que **as funções manipuladoras de mutação devem ser síncronas**. Por quê? Considere o seguinte exemplo:
+
+```js
+mutations: {
+  someMutation (state) {
+    api.callAsyncMethod(() => {
+      state.count++
+    })
+  }
+}
+```
+
+Agora imagine que estamos depurando a aplicação e observando os logs de mutação do _devtool_. Para cada mutação registrada, o _devtool_ precisará capturar os momentos "antes" e "depois" do estado. No entanto, o _callback_ assíncrono dentro da mutação de exemplo acima torna isso impossível: o _callback_ ainda não é chamado quando a mutação é confirmada (ou o _commit_ da mutação é feito) e não há como o _devtool_ saber quando o _callback_ será realmente chamado - qualquer mutação de estado executada no _callback_ é essencialmente impossível de rastrear!
+
+## Confirmando (ou fazendo Commits de) Mutações em Componentes
+
+Você pode confirmar (ou fazer _commit_ de) mutações em componentes com `this.$store.commit('xxx')`, ou use o método auxiliar `mapMutations` que mapeia métodos de componentes para chamadas `store.commit` (requer injeção do _store_ raiz):
+
+```js
+import { mapMutations } from 'vuex'
+
+export default {
+  // ...
+  methods: {
+    ...mapMutations([
+      'increment', // mapeia `this.increment()` para `this.$store.commit('increment')`
+
+      // `mapMutations` also supports payloads:
+      'incrementBy' // mapeia `this.incrementBy(amount)` para`this.$store.commit('incrementBy', amount)`
+    ]),
+    ...mapMutations({
+      add: 'increment' // mapeia `this.add()` para`this.$store.commit('increment')`
+    })
+  }
+}
+```
+
+## Vamos as Ações
+
+A assincronicidade combinada com mutação de estado pode tornar seu programa muito difícil de entender. Por exemplo, quando você chama dois métodos com retornos de _callbacks_ assíncronos que alteram o estado, como saber quando eles são chamados e qual retorno de _callback_ foi chamado primeiro? É exatamente por isso que queremos separar os dois conceitos. No Vuex, **mutações são transações síncronas**:
+
+```js
+store.commit('increment')
+// qualquer mudança de estado que a mutação "increment" pode causar
+// deve ser feito neste momento.
+```
+
+Para lidar com operações assíncronas, vamos apresentar [Ações](actions.md).

+ 137 - 0
docs/ptbr/guide/plugins.md

@@ -0,0 +1,137 @@
+# Plugins
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/cvp8ZkCR" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+Os _stores_ do Vuex aceitam a opção _plugins_ que expõe gatilhos (ou _hooks_) para cada mutação. Um _plugin_ Vuex é simplesmente uma função que recebe um _store_ como seu único argumento:
+
+```js
+const myPlugin = (store) => {
+  // chamado quando o store é inicializado
+  store.subscribe((mutation, state) => {
+    // chamada após cada mutação.
+    // A mutação vem no formato de `{ type, payload }`.
+  })
+}
+```
+
+E pode ser usada assim:
+
+```js
+const store = createStore({
+  // ...
+  plugins: [myPlugin]
+})
+```
+
+## Confirmando (ou fazendo _commit_ de) Mutações Dentro de Plugins
+
+_Plugins_ não tem permissão para alterar o estado diretamente - similar aos seus componentes, eles podem apenas acionar mudanças confirmando (ou fazendo o _commit_ de) mutações.
+
+Por confirmar (ou fazer _commit_ de) mutações, um _plugin_ pode ser usado para sincronizar uma fonte de dados ao _store_. Por exemplo, para sincronizar uma fonte de dados _websocket_ ao _store_ (isso é só um exemplo inventado, na realidade a função _createPlugin_ pode receber parâmetros adicionais para tarefas mais complexas):
+
+```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 = createStore({
+  state,
+  mutations,
+  plugins: [plugin]
+})
+```
+
+## Capturando os Momentos do Estado
+
+Às vezes, um _plugin_ pode querer receber "momentos" do estado, e também comparar o estado pós-mutação com o estado de pré-mutação. Para conseguir isso, você precisará realizar uma cópia-profunda do objeto de estado:
+
+```js
+const myPluginWithSnapshot = (store) => {
+  let prevState = _.cloneDeep(store.state)
+  store.subscribe((mutation, state) => {
+    let nextState = _.cloneDeep(state)
+
+    // compara `prevState` e `nextState`...
+
+    // salva o estado para a próxima mutação
+    prevState = nextState
+  })
+}
+```
+
+**_Plugins_ que capturam momentos do estado devem ser usados apenas durante o desenvolvimento.** Quando usamos _webpack_ ou _Browserify_, podemos construir nossas próprias ferramentas de distribuição (ou nossos próprios _builds_) que lidam com isso para nós:
+
+```js
+const store = createStore({
+  // ...
+  plugins: process.env.NODE_ENV !== 'production'
+    ? [myPluginWithSnapshot]
+    : []
+})
+```
+
+O _plugin_ vai ser usado por padrão. Para produção, você vai precisar do [DefinePlugin](https://webpack.js.org/plugins/define-plugin/) para webpack ou [envify](https://github.com/hughsk/envify) para Browserify para converter o valor do `process.env.NODE_ENV !== 'production'` para `false` na distribuição (ou _build_) final.
+
+## Plugin de Log Integrado
+
+Vuex vem com um _plugin_ de _log_ para casos comuns de depuração:
+
+```js
+import { createLogger } from 'vuex'
+
+const store = createStore({
+  plugins: [createLogger()]
+})
+```
+
+A função `createLogger` tem algumas opções:
+
+```js
+const logger = createLogger({
+  collapsed: false, // expande automaticamente mutações registradas no log
+  filter (mutation, stateBefore, stateAfter) {
+    // retorna `true` se uma mutação deve ser registrada no log
+    // `mutation` é um `{ type, payload }`
+    return mutation.type !== "aBlocklistedMutation"
+  },
+  actionFilter (action, state) {
+    // o mesmo que `filter`, mas para ações
+    // `action` é um `{ type, payload }`
+    return action.type !== "aBlocklistedAction"
+  },
+  transformer (state) {
+    // transforma o estado antes de regitrá-lo no log.
+    // por exemplo, retorna apenas uma sub-árvore específica
+    return state.subTree
+  },
+  mutationTransformer (mutation) {
+    // mutações são registradas no log no formato de  `{ type, payload }`
+    // mas podemos formatá-las como quisermos.
+    return mutation.type
+  },
+  actionTransformer (action) {
+    // O mesmo que mutationTransformer mas para ações
+    return action.type
+  },
+  logActions: true, // Log de Ações
+  logMutations: true, // Log de mutações
+  logger: console, // implementação da API `console`, valor padrão `console`
+})
+```
+
+O arquivo de _log_ também pode ser incluído diretamente via _tag_ `<script>`, e vai expor a função `createVuexLogger` globalmente.
+
+Perceba que o _plugin_ de _log_ captura momentos do estado, então use-o apenas durante o desenvolvimento.

+ 98 - 0
docs/ptbr/guide/state.md

@@ -0,0 +1,98 @@
+# Estado
+
+## Árvore Única de Estado
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/cWw3Zhb" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+Vuex usa uma **única árvore de estado** - ou seja, este único objeto contém todo o estado da sua aplicação e serve como "fonte única da verdade". Isso também significa que normalmente você terá apenas uma _store_ para cada aplicação. Uma única árvore de estado facilita a localização de uma parte específica do estado e nos permite capiturar facilmente momentos do estado atual da aplicação para fins de depuração.
+
+A árvore única de estado não entra em conflito com a modularidade - em capítulos posteriores, discutiremos como dividir seu estado e mutações em sub-módulos.
+
+Os dados que você armazena no Vuex seguem as mesmas regras que o `data` em uma instância do Vue, ou seja, o objeto de estado deve ser simples. **Veja também:** [Vue#data](https://v3.vuejs.org/api/options-data.html#data-2).
+
+## Obtendo o Estado Vuex nos Componentes Vue
+
+Então, como exibimos o estado dentro do _store_ em nossos componentes Vue? Como os _stores_ Vuex são reativos, a maneira mais simples de "recuperar" o estado dele é simplesmente retornar algum estado do _store_ de dentro de um [dado computado](https://vuejs.org/guide/computed.html):
+
+```js
+// vamos criar um componente de Contador
+const Counter = {
+  template: `<div>{{ count }}</div>`,
+  computed: {
+    count () {
+      return store.state.count
+    }
+  }
+}
+```
+
+Sempre que o `store.state.count` mudar, fará com que o dado computado seja reavaliado e ative as atualizações de DOM associadas.
+
+No entanto, esse padrão faz com que o componente dependa do _singleton_ do _store_ global. Ao usar um sistema de módulo, ele precisa importar o _store_ em todos os componentes que usam o estado do _store_ e também requer dados fictícios (ou _mocking_) ao testar o componente.
+
+O Vuex "injeta" o _store_ em todos os componentes filhos do componente raiz através do sistema de _plugins_ do Vue e estará disponível neles como `this.$store`. Vamos atualizar nossa implementação do `Counter`:
+
+```js
+const Counter = {
+  template: `<div>{{ count }}</div>`,
+  computed: {
+    count () {
+      return this.$store.state.count
+    }
+  }
+}
+```
+
+## O Método Auxiliar `mapState`
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/c8Pz7BSK" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+Quando um componente precisa usar várias propriedades ou _getters_ de estado do _store_, declarar todas esses dados computados pode ser repetitivo e verboso. Para lidar com isso, podemos fazer uso do método auxiliar `mapState` que gera funções _getter_ computadas para nós, economizando algumas linhas de código:
+
+```js
+// em builds completos, os métodos auxiliares são expostos como Vuex.mapState
+import { mapState } from 'vuex'
+
+export default {
+  // ...
+  computed: mapState({
+    // As arrow functions (ou funções de seta) podem tornar o código muito sucinto!
+    count: state => state.count,
+
+    // passar o valor da String 'count' é o mesmo que `state => state.count`
+    countAlias: 'count',
+
+    // para acessar o estado local com `this`, uma função normal deve ser usada
+    countPlusLocalState (state) {
+      return state.count + this.localCount
+    }
+  })
+}
+```
+
+Também podemos passar um _Array_ de _Strings_ para `mapState` quando o nome de um dado computado mapeado é o mesmo que um nome de árvore secundária do estado.
+
+```js
+computed: mapState([
+  // mapeia this.count para store.state.count
+  'count'
+])
+```
+
+## Objeto Spread Operator
+
+Observe que `mapState` retorna um objeto. Como usá-lo em combinação com outros dados computados locais? Normalmente, teríamos que usar um utilitário para fundir vários objetos em um para que possamos passar o objeto final para `computed`. No entanto, com o [objeto spread operator](https://github.com/tc39/proposal-object-rest-spread), podemos simplificar muito a sintaxe:
+
+```js
+computed: {
+  localComputed () { /* ... */ },
+  // mistura isso no objeto externo com o objeto spread operator
+  ...mapState({
+    // ...
+  })
+}
+```
+
+## Componentes Ainda Podem Ter Um Estado Local
+
+Usar Vuex não significa que você deve colocar **todo** o estado no Vuex. Embora colocar mais estado no Vuex torna suas mutações de estado mais explícitas e depuráveis, às vezes também pode tornar o código mais verboso e indireto. Se uma parte do estado pertencer estritamente a um único componente, não haverá problema em deixá-lo apenas como um estado local. Você deve pesar os prós e contras e tomar decisões que atendam às necessidades de desenvolvimento da sua aplicação.

+ 25 - 0
docs/ptbr/guide/strict.md

@@ -0,0 +1,25 @@
+# Strict Mode
+
+Para habilitar o modo estrito, simplesmente passe `strict: true` ao criar um _store_ Vuex:
+
+```js
+const store = createStore({
+  // ...
+  strict: true
+})
+```
+
+Em modo estrito, sempre que o estado do Vuex é mudado fora das funções manipuladoras de mutação, um erro será lançado. Isso garante que todas as mutações do estado possam ser explicitamente rastreadas por ferramentas de depuração.
+
+## Desenvolvimento vs. Produção
+
+**Não habilite o modo estrito ao fazer um _deploy_ para a produção!** O modo estrito executa um observador profundo síncrono na árvore de estados para detectar mutações inapropriadas e pode ser bastante caro quando você faz grande quantidade de mutações no estado. Certifique-se de desligá-lo em produção para evitar o custo de desempenho.
+
+Semelhante aos plugins, podemos deixar as ferramentas de compilação lidar com isso:
+
+```js
+const store = createStore({
+  // ...
+  strict: process.env.NODE_ENV !== 'production'
+})
+```

+ 32 - 0
docs/ptbr/guide/structure.md

@@ -0,0 +1,32 @@
+# Estrutura da Aplicação
+
+O Vuex não restringe realmente como você estrutura seu código. Em vez disso, ele impõe um conjunto de princípios de alto nível:
+
+1. O estado do nível da aplicação é centralizado no _store_.
+
+2. A única maneira de mudar o estado é confirmando (ou fazendo _commit_ das) **mutações**, que são transações síncronas.
+
+3. A lógica assíncrona deve ser encapsulada e pode ser composta com **ações**.
+
+Enquanto você seguir estas regras, depende de você como estruturar seu projeto. Se o arquivo do seu _store_ for muito grande, basta começar a dividir as ações, mutações e _getters_ em arquivos separados.
+
+Para qualquer aplicação mais complexa, provavelmente precisaremos aproveitar os módulos. Aqui está um exemplo de estrutura de projeto:
+
+```bash
+├── index.html
+├── main.js
+├── api
+│   └── ... # abstrações para fazer requisições a API
+├── components
+│   ├── App.vue
+│   └── ...
+└── store
+    ├── index.js          # onde montamos os módulos e exportamos o store
+    ├── actions.js        # ações raiz
+    ├── mutations.js      # mutações raiz
+    └── modules
+        ├── cart.js       # módulo cart
+        └── products.js   # módulo products
+```
+
+Como referência, confira o [Exemplo do Carrinho de Compras](https://github.com/vuejs/vuex/tree/4.0/examples/classic/shopping-cart).

+ 240 - 0
docs/ptbr/guide/testing.md

@@ -0,0 +1,240 @@
+# Testando
+
+<div class="scrimba"><a href="https://scrimba.com/p/pnyzgAP/cPGkpJhq" target="_blank" rel="noopener noreferrer">Tente esta lição no Scrimba</a></div>
+
+As partes principais que queremos testar unitáriamente no Vuex são mutações e ações.
+
+## Testando Mutações
+
+As mutações são muito simples de testar, porque são apenas funções que dependem completamente de seus argumentos. Um truque é que se você estiver usando módulos ES2015 e colocar suas mutações dentro do arquivo `store.js`, além da exportação padrão, você também deve exportar as mutações como uma exportação nomeada:
+
+```js
+const state = { ... }
+
+// exporta `mutações` como uma exportação nomeada
+export const mutations = { ... }
+
+export default createStore({
+  state,
+  mutations
+})
+```
+
+Exemplo de teste de uma mutação usando _Mocha_ + _Chai_ (você pode usar qualquer biblioteca de _framework_/_assertion_ que desejar):
+
+```js
+// mutations.js
+export const mutations = {
+  increment: state => state.count++
+}
+```
+
+```js
+// mutations.spec.js
+import { expect } from 'chai'
+import { mutations } from './store'
+
+// desestrutura `mutações` atribuidas
+const { increment } = mutations
+
+describe('mutations', () => {
+  it('INCREMENT', () => {
+    // estado mockado (ou simulado)
+    const state = { count: 0 }
+    // aplica a mutação
+    increment(state)
+    // afirma o resultado
+    expect(state.count).to.equal(1)
+  })
+})
+```
+
+## Testando Ações
+
+As ações podem ser um pouco mais complicadas porque podem chamar as APIs externas. Ao testar ações, geralmente precisamos fazer algum nível de _mocking_ - por exemplo, podemos abistrair as chamadas da API em um serviço e simular (ou mockar (_mock_)) esse serviço dentro de nossos testes. A fim de simular facilmente as dependências, podemos usar o _webpack_ e [inject-loader](https://github.com/plasticine/inject-loader) para empacotar (ou criar um _bundle_ dos) nossos arquivos de teste.
+
+Exemplo de teste de uma ação assíncrona:
+
+```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
+
+// use a sintaxe 'require' para inline loaders.
+// com inject-loader, isso retorna um factory de módulos
+// que nos permite injetar dependências mockadas (ou simuladas).
+import { expect } from 'chai'
+const actionsInjector = require('inject-loader!./actions')
+
+// cria o módulo com nossos mocks
+const actions = actionsInjector({
+  '../api/shop': {
+    getProducts (cb) {
+      setTimeout(() => {
+        cb([ /* resposta simulada */ ])
+      }, 100)
+    }
+  }
+})
+
+// método auxiliar para teste de ação com mutações esperadas
+const testAction = (action, payload, state, expectedMutations, done) => {
+  let count = 0
+
+  // confirmação simulada (ou mock commit)
+  const commit = (type, payload) => {
+    const mutation = expectedMutations[count]
+
+    try {
+      expect(type).to.equal(mutation.type)
+      expect(payload).to.deep.equal(mutation.payload)
+    } catch (error) {
+      done(error)
+    }
+
+    count++
+    if (count >= expectedMutations.length) {
+      done()
+    }
+  }
+
+  // chame a ação com store mockado (ou simulado) e argumentos
+  action({ commit, state }, payload)
+
+  // verifica se nenhuma mutação deveria ter sido despachada
+  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: { /* resposta simulada */ } }
+    ], done)
+  })
+})
+```
+
+Se você tem _spies_ disponíveis em seu ambiente de teste (por exemplo via [Sinon.JS](http://sinonjs.org/)), você pode usá-los em vez do método auxiliar `testAction`:
+
+```js
+describe('actions', () => {
+  it('getAllProducts', () => {
+    const commit = sinon.spy()
+    const state = {}
+
+    actions.getAllProducts({ commit, state })
+
+    expect(commit.args).to.deep.equal([
+      ['REQUEST_PRODUCTS'],
+      ['RECEIVE_PRODUCTS', { /* resposta simulada */ }]
+    ])
+  })
+})
+```
+
+## Testando Getters
+
+Se seus _getters_ tiverem um código complexo, vale a pena testá-los. Os _Getters_ também são muito simples de testar pelo mesmo motivo que as mutações.
+
+Exemplo testando um _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', () => {
+    // estado mockado (ou simulado)
+    const state = {
+      products: [
+        { id: 1, title: 'Apple', category: 'fruit' },
+        { id: 2, title: 'Orange', category: 'fruit' },
+        { id: 3, title: 'Carrot', category: 'vegetable' }
+      ]
+    }
+    // getter mockado (ou simulado)
+    const filterCategory = 'fruit'
+
+    // obtem o resultado do getter
+    const result = getters.filteredProducts(state, { filterCategory })
+
+    // afirma o resultado
+    expect(result).to.deep.equal([
+      { id: 1, title: 'Apple', category: 'fruit' },
+      { id: 2, title: 'Orange', category: 'fruit' }
+    ])
+  })
+})
+```
+
+## Executando Testes
+
+Se suas mutações e ações estiverem escritas corretamente, os testes não devem ter dependência direta das APIs do navegador após uma simulação apropriada. Assim, você pode simplesmente empacotar (ou criar um _bundle_) dos testes com o _webpack_ e executá-lo diretamente no _Node_. Alternativamente, você pode usar `mocha-loader` ou _Karma_ + `karma-webpack` para executar os testes em navegadores reais.
+
+### Executando no Node
+
+Crie a seguinte configuração de _webpack_ (juntamente com [`.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-loader',
+        exclude: /node_modules/
+      }
+    ]
+  }
+}
+```
+
+Então:
+
+``` bash
+webpack
+mocha test-bundle.js
+```
+
+### Executando no Navegador
+
+1. Instale o `mocha-loader`.
+2. Mude o `entry` da configuração do _webpack_ acima para `'mocha-loader!babel-loader!./test.js'`.
+3. Inicie o `webpack-dev-server` usando a configuração.
+4. Vá para `localhost:8080/webpack-dev-server/test-bundle`.
+
+### Executando no Navegador com Karma + karma-webpack
+
+Consulte a instalação na [documentação do vue-loader](https://vue-loader.vuejs.org/pt_BR/workflow/testing.html).

+ 134 - 0
docs/ptbr/guide/typescript-support.md

@@ -0,0 +1,134 @@
+# Suporte ao TypeScript
+
+O Vuex fornece suas tipagens para que você possa usar o TypeScript para escrever uma definição do _store_. Você não precisa de nenhuma configuração especial do TypeScript para Vuex. Por favor siga a [configuração básica do TypeScript no Vue](https://v3.vuejs.org/guide/typescript-support.html) para configurar seu projeto.
+
+No entanto, se você estiver escrevendo seus componentes Vue em TypeScript, há algumas etapas a seguir que exigem que você forneça a tipagem correta para um _store_.
+
+## Tipando a propriedade `$store` no Componente Vue
+
+O Vuex não fornece tipagens para a propriedade `this.$store` _out_ _of_ _the_ _box_. Quando usado com TypeScript, você deve declarar seu próprio _module_ _augmentation_.
+
+Para fazer isso, declare tipagens personalizadas para o `ComponentCustomProperties` do Vue adicionando um arquivo de declaração na pasta do seu projeto:
+
+```ts
+// vuex.d.ts
+import { ComponentCustomProperties } from 'vue'
+import { Store } from 'vuex'
+
+declare module '@vue/runtime-core' {
+  // declare seus próprios estados do store
+  interface State {
+    count: number
+  }
+
+  // fornece tipagem para `this.$store`
+  interface ComponentCustomProperties {
+    $store: Store<State>
+  }
+}
+```
+
+## Tipando a Função de Composição `useStore`
+
+Quando você está escrevendo seu componente Vue na API de Composição (ou _Composition_ API), provavelmente desejará que `useStore` retorne o _store_ tipado. Para que `useStore` retorne corretamente o _store_ tipado, você deve:
+
+1. Defina o `InjectionKey` tipado.
+2. Forneça o `InjectionKey` tipado ao instalar um _store_ na aplicação Vue.
+3. Passe o `InjectionKey` tipado para o método `useStore`.
+
+Vamos abordar isso passo a passo. Primeiro, defina a chave usando a interface `InjectionKey` do Vue junto com sua própria definição de tipo do _store_:
+
+```ts
+// store.ts
+import { InjectionKey } from 'vue'
+import { createStore, Store } from 'vuex'
+
+// defina suas tipagens para o estado do store
+export interface State {
+  count: number
+}
+
+// defina o injection key
+export const key: InjectionKey<Store<State>> = Symbol()
+
+export const store = createStore<State>({
+  state: {
+    count: 0
+  }
+})
+```
+
+Em seguida, passe o _injection_ _key_ definido ao instalar o _store_ para a aplicação Vue:
+
+```ts
+// main.ts
+import { createApp } from 'vue'
+import { store, key } from './store'
+
+const app = createApp({ ... })
+
+// passe o injection key
+app.use(store, key)
+
+app.mount('#app')
+```
+
+Finalmente, você pode passar a chave para o método `useStore` para recuperar o _store_ tipado.
+
+```ts
+// in a vue component
+import { useStore } from 'vuex'
+import { key } from './store'
+
+export default {
+  setup () {
+    const store = useStore(key)
+
+    store.state.count // tipado como number
+  }
+}
+```
+
+Por baixo dos panos, o Vuex instala o _store_ para a aplicação Vue usando o [Provide/Inject](https://v3.vuejs.org/api/composition-api.html#provide-inject) do Vue, característica que é a razão pela qual o _injection_ _key_ é um fator importante.
+
+### Simplificando o uso do `useStore`
+
+Ter que importar `InjectionKey` e passá-lo para `useStore` em todos os lugares em que é usado pode rapidamente se tornar uma tarefa repetitiva. Para simplificar as coisas, você pode definir sua própria função combinável (ou _composable_ _function_) para recuperar um _store_ tipado:
+
+```ts
+// store.js
+import { InjectionKey } from 'vue'
+import { createStore, useStore as baseUseStore, Store } from 'vuex'
+
+export interface State {
+  count: number
+}
+
+export const key: InjectionKey<Store<State>> = Symbol()
+
+export const store = createStore<State>({
+  state: {
+    count: 0
+  }
+})
+
+// defina sua própria função de composição `useStore`
+export function useStore () {
+  return baseUseStore(key)
+}
+```
+
+Agora, ao importar sua própria função combinável (ou _composable_ _function_), você pode recuperar o _store_ tipado **sem** ter que fornecer o _injection_ _key_ e ela está tipada:
+
+```ts
+// em um componente vue
+import { useStore } from './store'
+
+export default {
+  setup () {
+    const store = useStore()
+
+    store.state.count // tipado como number
+  }
+}
+```

+ 71 - 0
docs/ptbr/index.md

@@ -0,0 +1,71 @@
+# O que é Vuex?
+
+::: tip NOTE
+Esta documentação é para o Vuex 4, que funciona com Vue 3. Se você está procurando a documentação para o Vuex 3, que funciona com Vue 2, [por favor, confira aqui](https://vuex.vuejs.org/ptbr/).
+:::
+
+O Vuex é um **padrão de gerenciamento de estado + biblioteca** para aplicações Vue.js. Ele serve como um _store_ centralizado para todos os componentes em uma aplicação, com regras garantindo que o estado só possa ser mutado de forma previsível.
+
+## O que é um "Padrão de Gerenciamento do Estado"?
+
+Vamos começar com uma aplicação simples em Vue, um contador:
+
+```js
+const Counter = {
+  // state
+  data () {
+    return {
+      count: 0
+    }
+  },
+  // view
+  template: `
+    <div>{{ count }}</div>
+  `,
+  // actions
+  methods: {
+    increment () {
+      this.count++
+    }
+  }
+}
+
+createApp(Counter).mount('#app')
+```
+
+É uma aplicação independente com as seguintes partes:
+
+- O **estado** (_state_), que é a fonte da verdade que direciona nossa aplicação;
+- A **_view_**, que é apenas um mapeamento declarativo do **estado**;
+- As **ações** (_actions_), que são as possíveis maneiras pelas quais o estado pode mudar em reação às interações dos usuários da **_view_**.
+
+Esta é uma representação simples do conceito de "fluxo de dados unidirecional" (_one-way_):
+
+<p style="text-align: center; margin: 2em">
+  <img style="width:100%; max-width:450px;" src="/flow.png">
+</p>
+
+No entanto, a simplicidade é rapidamente descartada quando temos **vários componentes que compartilham um estado comum**:
+
+- Múltiplas _views_ que podem depender do mesmo pedaço de estado.
+- Ações de diferentes _views_ que podem precisar alterar o mesmo pedaço de estado.
+
+Para o problema um, passar tudo via propriedades (_props_) pode ser entediante para componentes profundamente aninhados e simplesmente não funciona para componentes irmãos. Para o problema dois, muitas vezes nos encontramos recorrendo a soluções como buscar referências diretas de instância pai / filho ou tentar mudar e sincronizar várias cópias do estado por meio de eventos. Ambos os padrões são frágeis e levam rapidamente a códigos impossíveis de manter.
+
+Então, por que não extraímos o estado compartilhado dos componentes, e o gerenciamos em um _singleton_ global? Com isso, nossa árvore de componentes se torna uma grande "_view_", e qualquer componente pode acessar o estado ou acionar ações, não importando onde elas estejam na árvore!
+
+Além disso, ao definir e separar os conceitos envolvidos no gerenciamento do estado e aplicar regras que mantêm a independência entre as _views_ e os estados, damos ao nosso código mais estrutura e capacidade de manutenção.
+
+Esta é a ideia básica por trás do Vuex, inspirado no [Flux](https://facebook.github.io/flux/docs/overview), [Redux](http://redux.js.org/) e [The Elm Architecture](https://guide.elm-lang.org/architecture/). Ao contrário dos outros padrões, o Vuex também é uma implementação da biblioteca adaptada especificamente para o Vue.js aproveitar as vantagens de seu sistema de reatividade granular para atualizações eficientes.
+
+Se você quiser aprender Vuex de uma forma interativa, você pode conferir esse [curso de Vuex no Scrimba](https://scrimba.com/g/gvuex), que oferece uma mistura de _screencast_ e _playground_ de código em que você pode pausar e brincar com o código a qualquer momento.
+
+![vuex](/vuex.png)
+
+## Quando usar o Vuex?
+
+Embora o Vuex nos ajude a lidar com o gerenciamento de estado compartilhado, ele também vem com o custo de mais conceitos e códigos repetitivos. É uma escolha de prós e contras entre produtividade de curto e longo prazo
+
+Se você nunca construiu um SPA em grande escala e for direto para o Vuex, ele pode parecer verboso e desanimador. Isso é perfeitamente normal - se o seu aplicativo é simples, você provavelmente ficará bem sem o Vuex. Um simples [store pattern](https://v3.vuejs.org/guide/state-management.html#simple-state-management-from-scratch) pode ser tudo que você precisa. Mas, se você está criando um SPA de médio a grande porte, é provável que tenha encontrado situações que fazem você pensar em como lidar melhor com o estado fora de seus componentes Vue, e o Vuex será naturalmente o próximo passo para você. Há uma boa citação de Dan Abramov, o autor do Redux:
+
+> As bibliotecas Flux são como óculos: você saberá quando precisar delas.

+ 65 - 0
docs/ptbr/installation.md

@@ -0,0 +1,65 @@
+# Instalação
+
+## Download Direto / CDN
+
+[https://unpkg.com/vuex](https://unpkg.com/vuex)
+
+<!--email_off-->
+[Unpkg.com](https://unpkg.com) fornece os links de CDN baseados em NPM. O link acima sempre apontará para a última versão do NPM. Você também pode usar uma versão/tag específica por meio de URLs como `https://unpkg.com/vuex@2.0.0`.
+<!--/email_off-->
+
+Inclua o `vuex` após o Vue e ele se instalará automaticamente:
+
+```html
+<script src="/path/to/vue.js"></script>
+<script src="/path/to/vuex.js"></script>
+```
+
+## NPM
+
+```bash
+npm install vuex@next --save
+```
+
+## Yarn
+
+```bash
+yarn add vuex@next --save
+```
+
+## Promise
+
+Vuex requer [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises). Se os seus navegadores não implementarem o _Promise_ (e.g. IE), você pode usar uma biblioteca _polyfill_, como a [es6-promise](https://github.com/stefanpenner/es6-promise).
+
+Você pode incluí-la via CDN:
+
+```html
+<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
+```
+
+Então o `window.Promise` estará disponível automaticamente.
+
+Se você preferir usar um gerenciador de pacotes como NPM ou Yarn, instale-o com os seguintes comandos:
+
+```bash
+npm install es6-promise --save # NPM
+yarn add es6-promise # Yarn
+```
+
+Além disso, adicione a linha abaixo em qualquer lugar no seu código antes de usar o Vuex:
+
+```js
+import 'es6-promise/auto'
+```
+
+## Dev Build
+
+Você terá que clonar diretamente do GitHub e fazer a distribuição (_build_) do `vuex` se
+quiser usar a compilação mais recente do dev.
+
+```bash
+git clone https://github.com/vuejs/vuex.git node_modules/vuex
+cd node_modules/vuex
+yarn
+yarn build
+```

+ 4 - 0
docs/public/_redirects

@@ -4,6 +4,10 @@
 /en/intro.html /en/guide/
 /en/* /guide/:splat
 
+/ptbr/api.html  /api/
+/ptbr/intro.html /ptbr/guide/
+/ptbr/* /guide/:splat
+
 /zh-cn/api.html  /zh/api/
 /zh-cn/intro.html /zh/guide/
 /zh-cn/* /zh/guide/:splat