五、核心概念Mutations
Mutation基本使用
更改Vuex的store中的状态的唯一方式就是提交muattion:
JavaScript mutations:{ increment(state){ state.counter++ }, decrement(state){ state.counter-- } }
Mutation携带数据
很多时候我们在提交mutation的时候,会携带一些数据,这个时候我们可以使用参数:
JavaScript mutations:{ // 普通的值 payload changeName(state,payload){ state.name = payload }, // payload为 对象类型 changeInfo(state,payload){ state.level = payload.level state.name = payload.name } } ===================================== changeInfo(){ this.$store.commit("changeInfo",{ name:"xxwn", level:999 }) }
对象风格的提交方式
JavaScript $store.commit({ type:"addNumber", count:100 }) |
Mutation常量类型
定义常量:mutation-type.js
JavaScript export const ADD_NUMBER = "ADD_NUMBER" |
定义mutation
JavaScript [ADD_NUMBER](state,payload){ state.counter += payload.count } |
提交mutation
JavaScript $store.commit({ type: ADD_NUMBER, count: 100 }) |
mapMutations辅助函数
我们也可以借助于辅助函数,帮助我们快速映射到对应的方法中:
在setup中使用也是一样的
mutation重要原则
mutation必须是同步函数
因为devtool工具会记录mutation的日记
每一条 mutation被记录,devtool都需要捕捉到前一状态和后一状态的快照;
但是在 mutation中执行异步操作,就无法追踪到数据的变化
六、核心概念Actions
actions的基本使用
Action类似于mutation,不同在于:
Action提交的是mutation,而不是直接变更状态
Action可以包含任意异步操作;
这里有一个非常重要的参数context:
context是一个和store实例均有相同方法和属性的context对象
所以我们可以从其中获取到commit方法来提交一个mutation,或者通过context.state和context.getters来获取state和getters
为什么它不是store对象? ==> 等说Modules再具体说
actions的分发操作
使用action => 进行action的分发:
分别使用store上的dispatch函数;
JavaScript add() { this.$store.dispatch("increment") } |
它可以携带参数:
JavaScript add(){ this.$store.dispatch("increment",{ count:100 }) } // =========================================== |
JavaScript nameBtnClick(){ this.$store.dispatch("changeNameActions","xiaoxiong") } // 传递给 下面的 // ==================================================== changeNameActions(context,payload){ // console.log(payload); // payload就是 传递过来的值 context.commit("changeName",payload) }
也可以以对象的形式进行分发(了解)
JavaScript add(){ this.$store.dispatch({ type:"increment", count:100 }) }
actions的辅助函数
action也有对应的辅助函数:
对象类型的写法;
数组类型的写法
JavaScript methods:{ ...mapActions(["increment","decrement"]), ...mapActions({ add:"increment", sub:"decrement" }) }
Options API
JavaScript methods:{ // actionBtnClick(){ // // 点击按钮 就派发 // this.$store.dispatch("incrementAction") // }, // nameBtnClick(){ // this.$store.dispatch("changeNameActions","xiaoxiong") // } // Options API写法 ...mapActions(["incrementAction","changeNameActions"]) }
Setup写法:
JavaScript <script setup> import { useStore,mapActions } from 'vuex' const store = useStore() // 在setup中使用mapActions辅助函数 const actions = mapActions(["incrementAction","changeNameActions"]) const newActions = {} Object.keys(actions).forEach(key => { newActions[key] = actions[key].bind({$store:store}) }) const { incrementAction,changeNameActions } = newActions // 2 使用默认的做法 function increment(){ store.dispatch("incrementAction") } </script>
actions的异步操作
Action通常是异步的,怎么知道action什么时候结束?
可以通过action返回Promise,在Promise的then中来处理完成后的操作;
七、核心概念Modules
module的基本使用
什么是Module?
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象,当应用变得非常复杂时,store对象就有可能变得臃肿;
为了解决以上问题,Vuex允许我们将store分割成 模块(module)
每个模块拥有自己的state,mutation,action,getter,甚至是嵌套子模块
module的局部状态
对于模块内部的mutation和getter,接收的第一个参数是 模块的局部状态对象
module的命名空间
默认情况下,模块内部的action和mutation仍然是注册在全局的命名空间中的,
这样使得多个模块能够对同一个action或mutation作出响应
Getter同样也默认注册在全局命名空间
如果我们希望模块具有更高的封装性和复用性,可以添加namespaced:true的方式使其成为带命名空间的模块;
当模块被注册后,他的所有getter action 及 mutation 都会自动根据模块注册的路径调整命名;
module修改或派发根组件
如果我们希望在action中修改root中的state,有以下的方式: