持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情juejin.cn/post/714765…
Mutation需要遵守Vue的响应规则
既然vuex的store中的状态是响应式的,那么当我们变更状态时,监视状态的vue组件也会自动更新,这也意味着vuex中的mutation也需要与vue一样遵守一些注意事项:
- 最好提前在你的store中初始化好所有所需属性
- 当需要在对象上添加新属性时,你应该
- 使用vue.use(obj,'newProp',123),或者
- 以新对象替换老对象,例如,使用对象展开运算符我们可以这样写:
使用常量替代mutation事件类型
使用常量替代mutation事件类型在各种Flux实现中是很常见的模式。这样可以使linter之类的工具发挥作用,同时把这些常量放在单独的文件中可以让你的代码合作者对整个app包含的mutation一目了然:
注意:要用[]括号括起来,可以在后面注释该常量具体用来做什么的,使别人阅读代码更加的容易,团队协作更高效。
mutation必须是同步函数
现在想像,我们正在debug一个app并且观察devtool中的mutation日志。每一条mutation被记录。devtools都需要捕捉到前一状态和后一状态的快照。然而,在上面的例子中mutation中的异步函数中的回调让这不可能完成:因为当mutation触发的时候,回调函数还没有被调用,devtools不知道什么时候回调函数实际上被调用---实质上任何在回调函数中进行的状态的改变都是不可追踪的。
在组件中提交mutation
可以在组件中使用this.$store.commit('...')提交mutation,或者使用mapMutations辅助函数将数组中的methods映射为store.commit调用(需要在根节点注入store)。
actions
actions写法类似于mutation,不同在于:
- action提交的是mutation,而不是直接变更状态
- action可以包含任意异步操作
action函数接收一个与store实例具有相同方法和属性的context对象,因此你可以调用context.commit提交一个mutation,或者通过context.state和context.getters来获取state和getters。
context的console结果
组合action
action通常是异步的,那么如何知道action是什么时候结束呢?更重要的是,我们如何才能组合多个action,以处理更加复杂的异步流程
首先,需要明白store.dispatch可以处理被触发的action的处理函数返回的Promise,并且store.dispatch仍旧返回promise:
下面的示例会先调用actionA, then方法之后调用后面的操作:
可以变成
另一个action中
最后,如果利用async/await,我们如下所示:
注意一个store.dispatch在不同模块中可以触发多个action函数。在这种情况下,只有当所有触发函数完成后,返回的promise才会执行。
modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时。store对象就有可能变得相当臃肿。
为了解决以上问题。vuex允许我们将store分割成模块。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块---从上至下进行同样方式的分割:
命名空间
默认情况下,模块内部的action、mutation和getter是注册在全局命名空间的---这样使得多个模块能够对同一mutation或action作出相应。
如果希望模块具有更高的封装度和复用性,可以通过添加namepaced:true的方式使其成为带命名空间的模块。当模块被注册之后,它的所有getter、action以及mutation都会自动根据模块注册的路径调整命名。例如:
启动了命名空间的getter和action会收到局部化的getter,dispatch和commit。换言之,你在使用模块内容时不需要在同一模块内额外添加空间名前缀。更改namespaced属性后不需要修改模块内的代码。(也就是前面的例子不需要在写点a和点b了)
项目结构
vuex并不限制代码结构,但是,它规定了一些需要遵守的规则:
- 应用层级的状态应该集中到单个store对象中
- 提交mutation是更改状态的唯一方法,并且这个过程是同步的。
- 异步逻辑都应该封装到action里面
目录:
开发环境与发布环境
不要再发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更--请确保再发布环境下关闭严格模式,以避免性能损失。
vuex核心流程中的主要功能
- vue Components是vue组件,组件会触发(dispatch)一些事件活动做。
- 在组件中发出的动作,肯定是想获取或者改变数据的,但是在vuex中,数据是集中管理的,不能直接去更改数据,所以会把这个动作提交(commit)到mutations中
- 然后mutations就去改变(mutation)state中的数据
- 当state中的数据被改变之后,就会重新渲染(render)到vue Components中去,组件展示更新后的数据,完成一个流程。
各模块在核心流程中能够的主要功能
- vue Components:vue组件。HTML页面是哪个,负责接收用户操作等交互行为,执行dispatch方法触发对应action进行回应。
- dispatch:操作行为触发方法,是唯一一个能执行action的方法
- actions:操作行为处理模块。负责处理vue。components接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序以此触发。向后台API请求的操作就在这个模块中进行。包括触发其他action以及提交mutation的操作。该模块提供了promise的封装,以支持action的链式触发。
- commit:状态改变提交操作方法。对mutation进行提交。是唯一能执行mutation的方法
- mutations:状态改变操作方法。是vuex修改state的唯一推荐方法,其他修改方式在严格模式下将会报错,该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些hook暴露出来,已进行state的监控等。
- state:页面状态管理容器对象。集中存储vueComponents中data对象的零散数据,全局唯一。以进行同一的状态管理。页面显示所需的数据从该对象中进行读取,利用vue的细粒度数据响应机制来进行高效的状态更新。
- getters:state对象读取方法。多数用于数据格式化。