vuex 中辅助函数mapState的基本用法详解

mapState 辅助函数

  当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:

// store.js
/**
    vuex的核心管理对象模块:store
 */
import Vue from 'vue';
import Vuex from 'vuex';
import vuexTest from './modules/vuexTest';

Vue.use(Vuex)
// 状态对象
const state = { // 初始化状态 这里放置的状态可以被多个组件共享
    count: 1,
    count1: 1,
    count2: 2,
    count3: 3,
    name: 'daming'
};
const mutations = {};
const actions = {};
const getters = {};

export default new Vuex.Store({
    state, // 状态
    mutations, // 包含多个更新state函数的对象
    actions, // 包含多个队形事件回调函数的对象
    getters, // 包含多个getter计算属性函数的对象
    modules: { // 模块化
        vuexTest
    }
});

 

  1、在界面或组件中不使用mapState获取vuex中state的状态

  虽然将所有的状态放入Vuex,会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态,比如temp变量,hello, number作为组件的局部状态。

<!-- test.vue -->
<template>
  <div id="example">
    {{count}}
    {{name}}
    {{helloName}}
    {{addNumber}}
  </div>
</template>

<script>
export default {
  data() {
    return {
      hello: 'hello',
      number: 1,
    }
  },
  computed: {

    // 由于 Vuex 的状态存储是响应式的,所以可以使用计算属性来获得某个状态
    // 通过下面的计算属性,就可以在当前组件中访问到count,name,helloName,addNumber 在模板中我们通过大括号符号打印出来,当然这些可以在vue中使用,比如在watch中监听,在mounted中使用

    // 下面的计算属性涉及到了vuex管理的状态
    count() { // 这实际上是ES6中对象的简化写法 完整写法是 count: function { return this.$store.state.count }
      return this.$store.state.count
    },
    name() { // 这实际上是ES6中对象的简化写法 完整写法是 name: function { return this.$store.state.count }
      return this.$store.state.count
    },
    helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
      return this.hello + this.$store.state.name
    },
    addNumber: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
      return this.number + this.$store.state.count
    }
    // 但有一个问题
    // 当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。比如上面的name(),count(),helloName(),显得重复,代码冗长
    // 为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:
  },
  watch: {
     helloName(newVal,oldVal){
         console.log(newVal);
         console.log(oldVal);
     } 
  },
  mounted(){
      console.log(this.helloName);
  }
}
</script>

  2、在组件、界面中使用mapState获取vuex中state的数据

<!-- test.vue -->
<template>
  <div id="example">
    {{count}}
    {{count1}}
    {{repeatCount}}
    {{count3}}
    {{name}}
    {{helloName}}
    {{addNumber}}
  </div>
</template>

<script>
export default {
  data() {
    return {
      hello: 'hello',
      number: 1,
      count2: 2
    }
  },
  computed: {
    /**
     * 数组形式
     * 当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。
     * */
    ...mapState(["count", "name"]),


    /**
     * 对象形式
     */
    ...mapState({
      count, // 这种就是count:"count", 的简写
      count1: "count1",
      repeatCount: "count2", // 当组件中与vuex中的字符已经出现重复时,使用 repeatCount 来映射 store.state.count2
      count3: (state) => { // 映射 count3 为 store.state.conut3的值
        return state.count3
      },
      helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
        return this.hello + state.name
      },
      addNumber: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
        return this.number + state.count
      }
    })
  },
  watch: {
    helloName(newVal, oldVal) {
      console.log(newVal);
      console.log(oldVal);
    }
  },
  mounted() {
    console.log(this.helloName);
  }
}
</script>

  3、modules的vuexTest模块中state数据

/**
 * vuexTest.js
 * modules 中的数据
 */
export default {
    namespaced: true,
    state: {
        moduleVal: 1,
        moduleName: "战战兢兢"
    },
    getters: {
    },
    mutations: {
    },
    actions: {
    }
}

  4、在界面或组件中不使用mapState获取模块modules vuexTest中state的状态

<!-- module test.vue -->
<template>
  <div id="example">
    {{moduleVal}}
    {{moduleName}}
    {{moduleNameOther}}
  </div>
</template>

<script>
export default {
  data() {
    return {
      hello: 'hello',
      number: 1,
    }
  },
  computed: {
    moduleVal(){
        return this.$store.state.vuexTest.moduleVal
    },
    moduleName(){
        return this.$store.state.vuexTest.moduleVal
    },
    moduleNameOther(){
        // 当组件中与vuex中的字符已经出现重复时,使用 moduleNameOther 来映射 store.state.vuexTest.moduleName
        return this.$store.state.vuexTest.moduleVal 
    },
    
  },
  watch: {
    helloName(newVal, oldVal) {
      console.log(newVal);
      console.log(oldVal);
    }
  },
  mounted() {
    console.log(this.addNumber);
  }
}
</script>

 

  5、在界面或组件中使用mapState获取模块modules vuexTest中state的状态

<!-- module test.vue -->
<template>
  <div id="example">
    {{moduleVal}}
    {{moduleName}}
    {{moduleNameOther}}
  </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
  data() {
    return {
      hello: 'hello',
      number: 1,
    }
  },
  computed: {
    /**
     * 数组形式
     * 当映射的计算属性的名称与 与模块中vuexTest中state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组,
     * */
    ...mapState("vuexTest", ["moduleVal", "moduleName"]),
    // "vuexTest" 指向模块vuexTest,"moduleVal"表示store.vuexTest.moduleVal


    /**
     * 对象形式
     */
    // 第一种对象方式
    ...mapState({
      moduleVal: "vuexTest/moduleVal",
      moduleNameOther: "vuexTest/moduleName" // 表示 moduleNameOther 映射到vuexTest模块中moduleName
    }),

    ...mapState("vuexTest", {
      moduleVal, // 这种就是moduleVal:"moduleVal", 的简写
      moduleName: "moduleName",
      moduleNameOther: "moduleName", // 当组件中与vuex中的字符已经出现重复时,使用 moduleNameOther 来映射 store.state.vuexTest.moduleName
      moduleVal: (state) => { // 映射 moduleVal 为 store.state.vuexTest.moduleVal的值
        return state.moduleVal
      },
      helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
        return this.hello + state.moduleName
      },
      addNumber(state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
        return this.number + state.moduleVal
      }
    })
  },
  watch: {
    helloName(newVal, oldVal) {
      console.log(newVal);
      console.log(oldVal);
    }
  },
  mounted() {
    console.log(this.addNumber);
  }
}
</script>

 

posted @ 2021-07-06 17:11  只争朝夕,不负韶华  阅读(22494)  评论(1编辑  收藏  举报