为Vue.js应用程序开发的状态管理模式
由 多个组件共享状态 引发的vue
1. 多个视图依赖于统一状态 2. 不一样视图的行为须要变动统一状态
每一个应用只包含一个Store实例
不能直接修改state。es6
两种方式:vuex
显式地提交 (commit) mutation缓存
异同点异步
不一样点:ide
使用commit的优势:函数
单一状态树
state派生状态
能够认为是 store的计算属性 : getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被从新计算
getters: { // 能够经过第二个参数getters来使用其余getter getterA: (state, getters) => { return getters.getterB.length }, getterB: (state) => { return state.todoList; }, getterC: (state) => (id) => { return state.todoList[id]; } }
经过属性访问:this.$store.getters.getterA工具
经过方法访问:this.$store.getters.getterC(1)性能
相似于事件
同步事务
用来更改Vuex的store中的状态
每一个mutation包含测试
回调函数 (handler): 进行状态更改的地方,接收state做为第一个参数
需遵照Vue的响应规则
Mutation必须是同步函数
devtools 不知道何时回调函数实际上被调用:在回调函数中进行的状态的改变都是不可追踪的
异步事务
相似Mutation,不一样在于:
Action函数接收与store实例具备相同方法和属性的context对象
actions: { // 常见用法,用es6的参数解构来简化代码 actionA({state, commit, getters, dispatch}) { } } // 使用action store.dispatch('actionA').then(() => { })
模块
解决的问题:应用复杂时(有不少的状态和逻辑),store对象会很臃肿
每一个模块拥有本身的state、getter、mutation、action、嵌套子模块module
命名空间
全局命名空间
,经过设置namespaced:true
可使其成为带命名空间的模块(局部化
)带命名空间的模块内访问全局内容:
state & getters
getters: { // 局部化后 getterA: (state, getters, rootState, rootGetters) => { } } actions: { actionA: ({dispatch, commit, getters, rootGetters, state, rootState}) => { } }
action: () => { dispatch('actionA', null, { root:true }); committ('mutationA', null, { root:true }); }
在带命名空间的模块内注册全局action
actions: { actionA: { root: true, handler(namespacedContext, payload) { ... } } }
模块动态注册: store.registerModule('moduleName', {})
- Vue插件能够在store中附加新模块,从而使用vuex来管理状态。例如:vuex-router-sync
模块卸载:store.unregisterModule(moduleName)
保留state: store.registerModule('a', module, { preserveState: true })
模块重用:
const MyReusableModule = { state () { return { foo: 'bar' } }, // mutation, action 和 getter 等等... }
在插件中不容许直接修改状态——相似于组件,只能经过提交 mutation 来触发变化。
const myPlugin = store => { // 当 store 初始化后调用 store.subscribe((mutation, state) => { // 每次 mutation 以后调用 // mutation 的格式为 { type, payload } }) } const store = new Vuex.Store({ // ... plugins: [myPlugin] })
开启严格模式,仅需在建立 store 的时候传入 strict: true
const store = new Vuex.Store({ // ... strict: true })
在严格模式下,不管什么时候发生了状态变动且不是由 mutation 函数引发的,将会抛出错误。这能保证全部的状态变动都能被调试工具跟踪到
不要在发布环境下启用严格模式: 严格模式会深度监测状态树来检测不合规的状态变动,会有性能损失
严格模式下,不要用v-model绑定state数据
** 这样会不使用mutation对state数据进行更改
两种方法
双向绑定的计算属性
computed: { message: { get () { return this.$store.state.obj.message }, set (value) { this.$store.commit('updateMessage', value) } } }