vue3.x实践经验-1、mapState、mapGetters、mapMutations、mapActions

一边学习vue3.x,一边实践,最近在做项目时,使用computed引入store中state的数据时,总是觉得很麻烦,想起新版兼容2.x,就想着引入mapState,可是怎么用都不对劲。后来,突然间醒悟过来,使用toRef或toRefs,就能实现mapState、mapGetters效果。
1、store.js

/*
 * @Descripttion: 
 * @version: X3版本
 * @Author: 
 * @Date: 2021-06-04 20:02:53
 * @LastEditors: 
 * @LastEditTime: 2021-06-04 20:16:48
 */
import { createStore } from 'vuex'

export default createStore({
  state: {
    num:10,
    str:'tom',
    arr:[1,2,4],
    obj:{
      name:'jerry',
      age:12
    }
  },
  getters:{
    getNum(state){
      return state.num+2;
    },
    getObj(state){
      
      return state.obj;
    }
  },
  mutations: {
    numMutation(state,data){
      state.num=data;
    },
    strMutation(state,data){
      state.str=data;
    },
    arrMutation(state,data){
      state.arr=data;
    },
    objMutation(state,data){
      state.obj=data;
    },
  },
  actions: {
    numAction({commit},args){
      commit('numMutation',args)
      console.log("numAction")
    }
  },
  modules: {
  }
})


2、App.vue


<template>
  <h4>state.num:h4>
  <span>{{ num }}span>
  <button @click="numAction[0](120)">numActionbutton>
  <br />

  <h4>state.str:h4>
  <span>{{ str }}span>
  <button @click="strMutation[0]('张三')">strMutationbutton> <br />
  <br />
  <span
    >state.arr:
    <h4>{{ arr }}h4>span
  >
  <br />
  <span
    >state.obj:
    <h4>{{ obj }}h4>span
  >
  <br />
  <span
    >state.getters.getNum:
    <h4>{{ getNum }}h4>span
  >
  <br />
  <span
    >state.getters.getObj:
    <h4>{{ getObj }}h4>span
  >
  <br />
template>
<script>
import { toRef, toRefs } from 'vue'
import { useStore } from 'vuex'
export default {
  setup() {
    const store = useStore();
    //mapState
    const { str, arr, obj } = toRefs(store.state);
    const num = toRef(store.state, 'num');
    //mapGetters
    const { getNum, getObj } = toRefs(store.getters);
    console.log('store:', store);
    //mapMutations(toRefs也可以,这里就不举例了)
    const strMutation = toRef(store._mutations, 'strMutation');
    //mapActions
    const numAction = toRef(store._actions, 'numAction');
    return {
      str,
      num,
      arr,
      obj,
      getNum,
      getObj,
      strMutation,
      numAction
    }
  },
}
script>
<style scoped>
button {
  width: 100px;
  height: 30px;
  margin-bottom: 20px;
}
style>

3、这里特殊说一下mapMutations和mapActions的替代方式
我们在生产环境下将store打印到控制台:
vue3.x实践经验-1、mapState、mapGetters、mapMutations、mapActions_第1张图片
可以看到:commit、dispatch、getters、state等属性都不是以下划线开头的,根据我以往的经验,以下划线开头的属性,在生产环境下,很可能就拿不到了,因此我特意去生产环境测试了一下,依然可以拿到_mutations和_actions这两个属性,然后通过toRef或toRefs拿到其中的函数,其实拿到的是一个数组:
vue3.x实践经验-1、mapState、mapGetters、mapMutations、mapActions_第2张图片
数组长度为一,数组内的元素实际就是我们想要的函数,因此才会出现: ,有个[0]
4、猜想:
感觉这个_mutations和_actions就是设计人员不想让我们使用,或者说不提倡我们使用,如果大家都这么用的话,那commit和dispatch就没必要存在了,我是觉得通过这种方式可以实现vue3.x环境下的mapMutations和mapActions,而且生产环境下也可以使用。希望后面vue的团队可以考虑下这方面吧(怎么在vue3.x实现mapMutations和mapActions),大家如果找到更好的方法,请@我,谢谢啦
5、后续:
之前是mapMutations和mapActions是通过toRef和toRefs实现的,后面想想觉得没必要,我们把数据用ref或者reactive封装一遍,是为了让数据具有响应性,能实现数据驱动视图。但是函数不需要,首先函数基本不会动态的改变,其次函数的调用相当于是引用传递,访问函数签名所在的地址,所以即使改变了,也会同步的。因此,根本不需要使用toRef或toRefs
代码如下:‘

<template>
  <h4>state.num:</h4>
  <span>{{ num }}</span>
  <button @click="numAction(120)">numAction</button>
  <br />

  <h4>state.str:</h4>
  <span>{{ str }}</span>
  <button @click="strMutation('张三')">strMutation</button> <br />
  <br />
  <span
    >state.arr:
    <h4>{{ arr }}</h4></span
  >
  <br />
  <span
    >state.obj:
    <h4>{{ obj }}</h4></span
  >
  <br />
  <span
    >state.getters.getNum:
    <h4>{{ getNum }}</h4></span
  >
  <br />
  <span
    >state.getters.getObj:
    <h4>{{ getObj }}</h4></span
  >
  <br />
</template>
<script>
import { toRef, toRefs } from 'vue'
import { useStore } from 'vuex'
export default {
  setup() {
    const store = useStore();
    //mapState
    const { str, arr, obj } = toRefs(store.state);
    const num = toRef(store.state, 'num');
    //mapGetters
    const { getNum, getObj } = toRefs(store.getters);
    console.log('store:', store);
    //mapMutations
    const { strMutation: [strMutation] } = store._mutations;
    console.log(strMutation)
    //mapActions
    const { numAction: [numAction] } = store._actions;
    return {
      str,
      num,
      arr,
      obj,
      getNum,
      getObj,
      strMutation,
      numAction
    }
  },
}
</script>
<style scoped>
button {
  width: 100px;
  height: 30px;
  margin-bottom: 20px;
}
</style>

通过es6的解构功能,直接将mutation或者action中的函数解构出来,不必考虑响应性问题。
之所以会出现{ strMutation: [strMutation] }这种形式,是为了避免前面说的[0]那种函数调用的形式,前面说了,直接结构出来是一个数组,这样美观程度上比较高。

你可能感兴趣的:(vue学习笔记,vue,js)