vuex
如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex):
我们通过提交mutation的方式,而非直接改变store.state.count,是因为我们想要更明确地追踪到状态的变化。store中的状态是响应式的。
核心概念
1.State
Vuex的状态存储是响应式的,从store实例中读取状态最简单的方法就是计算属性中返回某个状态;把store对象提供给‘store’选项,这可以把store的实例注入所有的子组件。
mapState辅助函数:帮助我们生成计算属性,减少重复和冗余。当映射的计算属性的名称与 state 的子节点名称相同时,
我们也可以给 mapState 传一个字符串数组。
对象展开运算符:...mapState({})使用对象展开运算符将此对象混入到外部对象中
组件仍然保有局部局部状态:不需要将所有状态放入Vuex
2.Getter
在store中定义‘getter’,getter的返回值会根据它的依赖被缓存起来,且只有它的依赖值发生了改变才会被重新计算。
通过属性访问:getter在通过属性访问时 是作为vue的响应式系统的一部分 缓存其中的。
通过方法访问:对store里的数组进行查询时非常有用,getter在通过方法访问时,每次都会去进行调用,而不会缓存结果。
mapGetters辅助函数:仅仅将store中的getter映射到局部计算属性,如果想将一个getter属性另取名字请使用对象属性。
3.Mutation
更改Vuex的store中的状态的唯一方法是提交mutation。每个mutation都一个字符串的事件类型和一个回调函数(type和handler),不能直接调一个mutation handler,你需要以相应的type调用store.commit方法。
提交载荷(Payload):向store.commit传入额外的参数,即mutation的载荷的Payload,载荷应该是一个对象,这样可以包含多个字段并且记录的mutation更易读。
对象风格的提交方式:直接使用包含type属性的对象,整个对象作为载荷传给mutation函数,handler保持不变。
Mutation需遵守Vue的响应规则:a最好提前在你的 store 中初始化好所需属性。
b当需要在对象上添加新属性时,你应该使用 Vue.set(obj, 'newProp', 123), 或者以新对象替换 老对象。
使用常量替代mutation事件类型:在各种Flux实现中是很常见的模式,多人协作中有帮助用不用随便。
Mutation必须是同步函数
在组件中提交Mutation:可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为
store.commit 调用(需要在根节点注入 store)。
4.Action
处理异步操作
分发action:Action 通过 store.dispatch 方法触发:
在组件中分发action:组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映 射为store.dispatch 调用(需要先在根节点注入 store)。
组合action:如果我们利用 async / await,组合 action。一个 store.dispatch 在不同模块中可以触发多个 action 函数。在这种情 况下,只有当所有触发函数完成后,返回的 Promise 才会执行。
5.Module
为了解决一个比较大的对象,Vuex允许我们将store分割成模块。
模块的局部状态:a>对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。
b>于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState
c>对于模块内部的 getter,根节点状态会作为第三个参数暴露出来
命名空间:模块内部的 action、mutation 和 getter 是注册在全局命名空间的。通过添加 namespaced: true 的方式使其成为带命 名空间的模块,具有更高的封装度和复用性。
在带命名空间的模块内访问全局内容:如果你希望使用全局 state 和 getter,rootState 和 rootGetter 会作为第三和第四参数传入getter,也会通过 context 对象的属性传入 action;若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给dispatch 或 commit 即可。
在带命名空间的模块注册全局 action:要在带命名空间的模块注册全局 action,你可添加 root: true,并将这个 action的定义放在函数 handler 中。
带命名空间的绑定函数。
给插件开发者的注意事项:过插件的参数对象来允许用户指定空间名称。
模块动态注册:在 store 创建之后,你可以使用 store.registerModule 方法注册模块。
模块重用。
//项目结构
规则:应用层级的状态应该集中到单个 store 对象中。
提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
异步逻辑都应该封装到 action 里面。
ps:具体可参考购物车示例
//插件 Vuex插件就是一个函数,它接受store作为唯一参数。
在插件内提交Mutation:在插件中不允许直接修改状态,只能通过提交mutation来触发变化。
生成State快照:对状态对象进行深拷贝。生成状态快照的插件应该只在开发阶段使用,使用 webpack 或 Browserify,让构建工具帮我们处理。
内置 Logger 插件:日志插件还可以直接通过 <script> 标签引入,它会提供全局方法 createVuexLogger。
logger 插件会生成状态快照,所以仅在开发环境使用。
//严格模式 在创建 store 的时候传入 strict: true。不要在发布环境下启用严格模式!
//表单处理 双向绑定的数据统计:使用带有 setter 的双向绑定计算属性。
//测试 测试Mutation、Action(为了便于解决 mock 依赖,可以用 webpack 和 inject-loader 打包测试文件)、Getter
执行测试:如果你的 mutation 和 action 编写正确,经过合理地 mocking 处理之后这些测试应该不依赖任何浏览器 API,因此你可以直接用。
webpack 打包这些测试文件然后在 Node 中执行。也可以用 mocha-loader,在浏览器中测试。具体配置: https://vuex.vuejs.org/zh/guide/testing.html
//热重载 对于 mutation 和模块,你需要使用 store.hotUpdate() 方法。