vuex原理

2019-08-14  本文已影响0人  逆风飘游的鱼

https://github.com/answershuto/learnVue/tree/master/docs

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

#什么是“状态管理模式”?这个状态自管理应用包含以下几个部分:state,驱动应用的数据源;view,以声明方式将 state 映射到视图;actions,响应在 view 上的用户输入导致的状态变化。

但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:多个视图依赖于同一状态。来自不同视图的行为需要变更同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

因此,把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!

StateGetterMutationActionModule项目结构插件严格模式表单处理测试热重载

开始

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:1.Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。2.你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)conststore=newVuex.Store({state:{count:0},mutations:{increment(state){state.count++}}})

现在,你可以通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更:

store.commit('increment')console.log(store.state.count)// -> 1

再次强调,我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。

由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutation。

API 参考

#Vuex.Store

importVuexfrom'vuex'conststore=newVuex.Store({...options})

#Vuex.Store 构造器选项

#state

类型: Object | Function

Vuex store 实例的根 state 对象。详细介绍

如果你传入返回一个对象的函数,其返回的对象会被用作根 state。这在你想要重用 state 对象,尤其是对于重用 module 来说非常有用。详细介绍

#mutations

类型: { [type: string]: Function }

在 store 上注册 mutation,处理函数总是接受 state 作为第一个参数(如果定义在模块中,则为模块的局部状态),payload 作为第二个参数(可选)。

详细介绍

#actions

类型: { [type: string]: Function }

在 store 上注册 action。处理函数总是接受 context 作为第一个参数,payload 作为第二个参数(可选)。

context 对象包含以下属性:{state,// 等同于 `store.state`,若在模块中则为局部状态rootState,// 等同于 `store.state`,只存在于模块中commit,// 等同于 `store.commit`dispatch,// 等同于 `store.dispatch`getters,// 等同于 `store.getters`rootGetters// 等同于 `store.getters`,只存在于模块中}

同时如果有第二个参数 payload 的话也能够接收。

#getters

类型: { [key: string]: Function }

在 store 上注册 getter,getter 方法接受以下参数:state,    // 如果在模块中定义则为模块的局部状态                              getters,  // 等同于 store.getters

注册的 getter 暴露为 store.getters。

#modules

类型: Object

包含了子模块的对象,会被合并到 store,大概长这样:

{key:{state,namespaced?,mutations,actions?,getters?,modules?},...}

与根模块的选项一样,每个模块也包含 state 和 mutations 选项。模块的状态使用 key 关联到 store 的根状态。模块的 mutation 和 getter 只会接收 module 的局部状态作为第一个参数,而不是根状态,并且模块 action 的 context.state 同样指向局部状态。

#Vuex.Store 实例属性

#state

类型: Object

根状态,只读。

#getters

类型: Object

暴露出注册的 getter,只读。

#Vuex.Store 实例方法

#commit

commit(type: string, payload?: any, options?: Object)

commit(mutation: Object, options?: Object)

提交 mutation。options 里可以有 root: true,它允许在命名空间模块里提交根的 mutation。详细介绍

#dispatch

dispatch(type: string, payload?: any, options?: Object)

dispatch(action: Object, options?: Object)

分发 action。options 里可以有 root: true,它允许在命名空间模块里分发根的 action。返回一个解析所有被触发的 action 处理器的 Promise。详细介绍

#组件绑定的辅助函数

#mapState

mapState(namespace?: string, map: Array<string> | Object<string | function>): Object

为组件创建计算属性以返回 Vuex store 中的状态。详细介绍

第一个参数是可选的,可以是一个命名空间字符串。详细介绍

对象形式的第二个参数的成员可以是一个函数。function(state: any)

#mapGetters

mapGetters(namespace?: string, map: Array<string> | Object<string>): Object

为组件创建计算属性以返回 getter 的返回值。详细介绍

第一个参数是可选的,可以是一个命名空间字符串。详细介绍

#mapActions

mapActions(namespace?: string, map: Array<string> | Object<string | function>): Object

创建组件方法分发 action。详细介绍

第一个参数是可选的,可以是一个命名空间字符串。详细介绍

对象形式的第二个参数的成员可以是一个函数。function(dispatch: function, ...args: any[])

#mapMutations

mapMutations(namespace?: string, map: Array<string> | Object<string | function>): Object

创建组件方法提交 mutation。详细介绍

第一个参数是可选的,可以是一个命名空间字符串。详细介绍

对象形式的第二个参数的成员可以是一个函数。function(commit: function, ...args: any[])


上一篇 下一篇

猜你喜欢

热点阅读