Vuex 状态管理
组件层和数据层抽离,组件层单纯展示,把数据层放到全局,形成一个单一的 store,所有的数据变更都要经过 stroe 来进行,形成单向数据流,使数据变化变化变得可预测。
vuex 将共享的数据抽离到全局以一个单例存放。
所有修改 state 的操作只能通过 Mutation 进行,Mutation 同时提供了观察者模式,供外部获取 state 数据的更新,所有异步接口走 Action,Action 内部还是通过 mutation 改变 state,最后 state 变化引起页面更新。
Vuex 运行依赖 vue 实现的数据双向绑定,需要 new Vue 来实现响应化,所以 vuex 是专门为 vue.js 实现的状态管理库,严格模式下,不是通过 mutation 改变 state 都会报错,Vue 通过 Vue.use()来安装一个插件,内部会调用插件的 insatll 方法。
安装
首先会检查是否重复安装了 然后根据 vue 版本实现不同的安装办法
- 1.0 Vue._init 方法中
- 2.0 Vue 的 beforeCreate 钩子中,$options.store 存在的化 说明是 Root 节点,若不存在则是子组件,则从父组件的 option 中拿 ,这样每个组件都可以通过 this.$store 访问全局 store 实例
构造函数
判断环境信息,是否支持 promise,是否通过 new store 等然后开始
初始化变量
- _committing 用于在严格模式下是否是用 mutation 改变 state 等
- _wrappedGetters 存放 getter
- _action // 存放 actions
将 dispatch/commit 调用的 this 绑定为 store 实例,否则在组件内部 this.dispatch 时的 this 会指向组件的 vm
初始化根 module,同时递归注册子 module,收集所有的 module 的 getter 到 _wrappedGetters
installMudule(this,state,[],this._module.root)
resetStoreVM(this,state) // 通过 VM 使 store 变成响应式的
plugins.forEach(plugin => plugin(this)) // 调用插件
installMudule 仔细看看吧
判断是否是 根 module,如果有 namespace 则在 _modulesNamespaceMap 中注册
Vue.set(parentState,modulename,state)
///* 将子 module 设成响应式的 */
遍历注册 action mutation getters 然后递归安装子 module
registerActions 时,将 push 进_actions 的 action 进行了一层封装(wrappedActionHandler,)所以我们在进行 dispatch 的第一个参数中获取 state、commit 等方法。执行结果 res 会被进行判断是否是 Promise,不是则会进行一层封装,将其转化成 Promise 对象。
registerGetter 时 就是在把 module 中的 getter 收集到 store._warppedGetters 中,resetStoreVM--resetStoreVM 首先会遍历 wrappedGetters,使用 Object.defineProperty 方法为每一个 getter 绑定上 get 方法,这样我们就可以在组件里访问 this.$store.getters.test 就等同于访问 store._vm.test。
新建 Vue 对象通过 vue 内部的响应式实现注册 store 中的 state 和 computed,对于旧的 Vue 对象,解除旧 vm 的 state 的引用,以及销毁旧的 Vue 对象
resetStoreVM
严格模式
strict 参数可以控制 Vuex 的严格模式上
store._vm.watch(function() {return this._data.$$state },()=> { // 断言判断_committing 是否使 true 从而判断是否是通过 mutation 改变的 }) commit store 中的 commit 方法中执行 mutation 的语句是这样的。 this._withCommit(() => { entry.forEach(function commitIterator (handler) { handler(payload) }) })
commit 方法会根据 type 找到并调用_mutations 中的所有 type 对应的 mutation 方法,所以当没有 namespace 的时候,commit 方法会触发所有 module 中的 mutation 方法。再执行完所有的 mutation 之后会执行 _subscribers 中的所有订阅者。我们来看一下_subscribers 是什么。
Store 给外部提供了一个 subscribe 方法,用以注册一个订阅函数,会 push 到 Store 实例的_subscribers 中
dispatch
1. actions 中取出 type 对应的 action
2. 是数组则包装 Promise 形成一个新的 Promise,只有一个则直接返回第 0 个
registerModule
动态注册 module,内部实现实际上也只有 installModule 与 resetStoreVM 两个步骤,前面已经讲过,这里不再累述。
resetStore,将 store 中的_actions 等进行初始化以后,重新执行 installModule 与 resetStoreVM 来初始化 module 以及用 Vue 特性使其“响应式化”,这跟构造函数中的是一致的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论