vuex原理

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[])


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • {"keys":[{"key2":"余华","key":"活着","url":"https://www.jians...
    书籍数据记录阅读 471评论 0 0
  • 不过今年,情况可大不一样了。 村里拥有了三间刚建的崭新的教室。 新教室看起来结实又整洁,里面也很宽敞。即使天气很热...
    TroubleMak_5e6c阅读 141评论 0 0
  • 假期最后一天已经过去 休息好了 心情也跟着好了 看到群里挺多的单子 还有账目没有对 明天上班把张对好 迎接五月
    上官华雪阅读 118评论 0 0
  • 一年读两百本书难么? 对于想读书的人来说,一年两百本书真的不难。 对于有钱,有时间又想读书的人来说,别说两百,三百...
    指尖流失的狗毛阅读 252评论 0 0