Estado
Árvore Única de Estado
O Vuex usa uma árvore única de estado - ou seja, esse único objeto contém todo o estado do seu nível de aplicação e serve como a "única fonte da verdade". Isso também significa que você terá apenas um store para cada aplicativo. Uma árvore única de estado facilita a localização de uma parte específica do estado, e permite capturar facilmente momentos do estado atual do aplicativo 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.
O tipo de dados guardados no Vuex segue as mesmas regras que data
em instâncias Vue, ou seja o state têm de ser um objeto simples. Detalhes
Obtendo o Estado Vuex nos Componentes Vue
Então, como exibimos o estado dentro do store em nossos componentes Vue? Uma vez que os stores Vuex são reativos, a maneira mais simples de "recuperar" o estado é simplesmente retornar algum estado do store dentro de um dado computado:
// vamos criar um componente de Contador
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return store.state.count
}
}
}
Sempre que o store.state.count muda, 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 store singleton 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 mocking ao testar o componente.
O Vuex fornece um mecanismo para "injetar" o store em todos os componentes filho do componente raiz com a opção store (habilitada por Vue.use(Vuex)
):
const app = new Vue({
el: '#app',
// fornece o store usando a opção "store".
// isso irá injetar a instância do store em todos os componentes filhos.
store,
components: { Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})
Ao fornecer a opção store para a instância raiz, o store será injetado em todos os componentes filho da raiz e estará disponível neles como this.$store
. Vamos atualizar a nossa implementação Counter:
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
mapState
O Auxiliar Quando um componente precisa fazer uso de várias propriedades do estado do store ou getters, declarar todos esses dados computados pode ser repetitivo e verboso. Para lidar com isso, podemos usar o auxiliar mapState
que gera funções getter computadas para nós, economizando algumas linhas de código:
// em builds completos, os 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.
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 computado
. No entanto, com o Spread Operator (que é uma proposta de ECMAScript em estágio 4), podemos simplificar muito a sintaxe:
computed: {
localComputed () { /* ... */ },
// mistura isso no objeto externo com o objeto spread operator
...mapState({
// ...
})
}
Componentes Ainda Podem Ter Um Estado Local
O uso do Vuex não significa que você deve colocar tudo no estado do 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 um pedaço de estado pertence estritamente a um único componente, pode ser bom 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.