Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采取集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。每一个Vuex应用的核心是store,它包含中应用中的大部分状态(state)。Vuex和全局对象有以下两点不同:
1,Vuex中的状态存储是响应式的。当vue组件从store中读取状态的时候,若store中的状态发生变化的时候,那么相应的组件也会得到更新
2,改变store中的状态唯一方法就是显性的提交(commit)mutation。
几个核心概念:
State
如何在vue组件中展示状态?由于Vuex的存储状态是响应式的,最简单的方法就是在计算属性中返回某个状态:
const Counter = { template : `<div>{{count}}</div>`, computed: { count () { return store.state.count } } } 每当store.state.count变化的时候,都会重新求取计算属性,并且触发相关联的DOM
Getter
Vuex允许我们在store中定义'getter'(可以认为是store的计算属性),就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖发生了变化才会被重新计算。
const store = new Vuex.Store({ state : { todo: [ {id:1,text: '...',done: true}, {id:2,text: '...',done: false} ] }, getters: { doneTodos: (state)=> { return store.state.todo.filter(todo = > todo.done) } } })
Getter会暴露为store.getters对象:
store.getters.doneTodos // 返回。 [{id:1,text: '...',done: true}]
mapGetters 辅助函数
mapGetters 辅助函数仅仅是将store中的getter映射到局部计算属性
import {mapGetters} from 'vuex' export default { computed: { ...mapGetters(['doneTodos']) } } 如果想将其中的一个getter改变为另外一个名字,则使用对象形式 export default { computed: { ...mapGetters({ donetode: 'doneTodos' }) } }
Mutation
更改Vuex的store中状态的唯一方法是提交mutation,Vuex中的mutation非常类似于事件,每一个mutation都有一个字符串的事件类型(type)和一个回调函数,这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数,需要注意一点的是mutation里面全部都是同步操作
对象风格的提交方式
提交mutation的另一种方式是直接使用包含type属性的对象:
使用常量替代mutation事件类型是很常见的的模式
//mutation-type.js export const SOME_MUTATION = 'SOME_MUTATION' // store.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) import {SOME_MUTATION} from './mutation-type.js' const store = new Vuex.Store({ state: {....} mutations: { [SOME_MUTATION] (state,payload) { // 可以使用es2015风格使用一个常量作为属性名 ... // 常规操作 } } }) // vue组件中的使用 方法一: import {SOME_MUTATION} from './mutation-type.js' // 需要存值的地方 this.$store.commit(SOME_MUTATION,{}) 方法二: 使用辅助函数mapMutations将组件中的methods映射为store.commit调用 import {mapMutation} from 'vuex' export default { methods: { this.someMutation({}) // 需要存值的地方 ...mapMutations({ someMutation: 'SOME_MUTATION' // 将this.someMutation()映射为this.$store.commit(SOME_MUTATION,{}) }) } }
Action
Action类似于mutation,但是Action是用来提交mutation的,不是来提交状态的改变的,并且Action可以包含任何异步操作
const store = new Vuex.Store({ state:{ count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } } }) ES6中简写actions actions: { increment ({commit}) { commit('increment') } }
Action函数接受一个与store实例具有相同方法和属性的context对象,因此可以通过context.commit(),提交一个mutation,还可以通过context.state和context.getters来获取state和getter
分发Action this.$store.dispatch()
Module
由于使用单一的状态树,应用的所有的状态都会集中到一个比较大的对象,当应用变得非常复杂时,store对象就可能变得非常臃肿,为了解决以上问题,Vuex允许可以将store分割成模块儿(module),每个模块儿都拥有自己的state,getter,mutation,action
具体例子如下:
const moduleA = { state: {...}, mutations:{...}, getters: {...}, actions: {...} } const moduleB = { state: {...}, mutations: {...}, getters: {...}, actions: {...} } const store = new Vuex.Store({ modules:{ a:moduleA, b:moduleB } })
可以通过store.state.a //访问到moduleA的状态
store.state.b // 访问到moduleB的状态
这个module依据项目的大小以及人员配合而定,不一定都得使用