VUE3之VUEX

mapMutations

在computed中使用:

import {mapMutations} from 'vuex'
  export default {
    methods: {
      ...mapMutations(["increment","decrement","increment_n"])
    }
  }

在setup中使用:

import {mapMutations} from 'vuex'
  export default {
    setup(props) {
      const storeMutations = mapMutations(["increment","decrement","increment_n"]);
      return {
        ...storeMutations
      }
    }
  }

actions

action中可以进行异步的操作,处理完的结果也需要通过commit方法让mutations进行数据处理。

actions中的方法有一个context参数,它类似于store,但是在modules中可能会有所不同:

  actions:{
    incrementAction(context){
      setTimeout(() => {
        context.commit("increment")
      }, 1000);
    }
  }

第二个参数同mutations中的一样,是一个从外面传入的参数:

  actions:{
    incrementAction(context,payload){
      console.log(payload)
      setTimeout(() => {
        context.commit("increment")
      }, 1000);
    },
    methods: { 
      increment(){
        this.$store.dispatch("incrementAction",{name:"shopkeeper"});
      }
    },

在组件中调用actions的方式:

    methods: { 
      increment(){
        this.$store.dispatch("incrementAction");
      }
    },

一般来说,我们会在actions编写网络请求数据的操作,以下是一个结合axios的小例子:

  actions:{
    getHomeUserData(context){
      axios.get("http://139.155.47.131/users").then(
        res=>{
          context.commit("addUserData",res.data)
        }
      )
    }
  }
    mounted() {
      this.$store.dispatch("getHomeUserData");
    },

context还有其它的一些属性,可以在需要的时候调用:

actions如同mutations一样有另一种派发风格,即写成一个对象:

decrement(){
  this.$store.dispatch({
    type:"decrementAction"
  })
}

mapActions

在methods中使用:

methods: {
  ...mapActions(["incrementAction","decrementAction"]),
  ...mapActions({
    add:"incrementActions",
    sub:"decrementActions"
  })
},

在setup中使用:

setup(props) {
  const actions = mapActions(["incrementAction","decrementAction"])
  return {
    ...actions
  }
}

actions的返回值

actions的返回值默认为undefined,实际上可以返回一个promise,以监听数据何时加载完毕:

  actions:{
    getHomeUserData2(context){
      return new Promise((resolve,reject)=>{
        axios.get("http://139.155.47.131/users").then(
          res=>{
            context.commit("addUserData",res.data)
            resolve("success")
          }
        ).catch(err =>{
          reject(err)
        })
      })
    },
  }
    setup(props) {
      const store = useStore();
      onMounted(()=>{
        const promise=store.dispatch("getHomeUserData2");
        promise.then(res=>{
          console.log(res)
        }).catch(err=>{
          console.log(err)
        })
      })
    }

modules

基本使用:为每一个组件单独定义一个module对象,其中包含state、mutations等store中的属性。在根store中的modules属性中配置之:

const homeModule = {
  state(){
    return {
      counter: 100
    }
  },
  getters:{

  },
  mutations:{

  },
  actions:{

  }
}

export default homeModule
import {createStore} from 'vuex';
import home from './modules/home';
import user from './modules/user';
const store = createStore({
  modules:{
    home,
    user 
  }
});

export default store;

modules的命名空间

默认情况下:modules中只有state是独占的(需要使用state.xxx获取),其它的属性mutations等都是合并到根store中。此时使用getters、mutations或者actions,将会触发所有同名的变量。

如果想让module独占其内部的属性,需要加上namespaced:true:

const homeModule = {
  namespaced:true,
  state(){
    return {
      counter: 100
    }
  },
  getters:{
    doubleHomeCounter(state){
      return state.counter*2;
    }
  },
  mutations:{
    increment(state){
      state.counter++;
    }
  },
  actions:{
    incrementAction(context){
      context.commit("increment")
    }
  }
}

export default homeModule

需要通过类似于url的方式访问:

<template>
  <div>
    <hr>
    <h2>当前home计数:{{$store.state.home.counter}}</h2>
    <button @click="homeIncrement">home+1</button>
    <h2>{{$store.getters["home/doubleHomeCounter"]}}</h2>
    <button @click="homeIncrementAction">home increment action</button>
    <hr>
  </div>
</template>

<script>
import {useStore, mapActions} from 'vuex'
  export default {
    methods: {
      homeIncrement(){
        this.$store.commit("home/increment")
      },
      homeIncrementAction(){
        this.$store.dispatch("home/incrementAction")
      }
    },
  }
</script>

modules的其它一些细节

module中的getters方法,除了本有的state和getters参数外,还能获取到rootState和rootGetters。

  getters:{
    doubleHomeCounter(state,getters,rootState,rootGetters){
      return state.counter*2;
    }
  },

module中的actions方法,其入参context对象有commit、dispatch、state、rootState、getters、rootGetters属性。

  actions:{
    incrementAction({commit, dispatch, state, getters, rootState, rootGetters}){
      commit("increment")
    }
  }

在commit和dispatch中,如果想要对根中的mutations操作,需要在第三个参数中增加{root: true}:

commit("increment",null,{root: true})

modules中的辅助函数

如何对modules使用mapState等辅助函数,在options API中有两种写法,一种是直接通过根store来获取,那么需要一个namespace的参数;另一种是使用createNamespacedHelpers函数来对module进行操作:

import { createNamespacedHelpers} from 'vuex'
const {mapState,mapGetters,mapMutations,mapActions} = createNamespacedHelpers("home")
  export default {
    computed:{      
      //写法1:直接从根中获取
      // ...mapState("home",["counter"]),
      // ...mapGetters("home",["doubleHomeCounter"])

      // 写法2:从home中获取
      ...mapState(["counter"]),
      ...mapGetters(["doubleHomeCounter"])
    },
    methods: {
      // 写法1:直接从根中获取
      // ...mapMutations("home",["increment"]),
      // ...mapActions("home",["incrementAction"])

      // 写法2:从home中获取
      ...mapMutations(["increment"]),
      ...mapActions(["incrementAction"])
    },
  }

在composition API中:

One thought on “VUE3之VUEX

发表评论