vuex学习与实践——mapState、getter、mapGetters

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

import { mapState } from 'vuex'
2)mapState使用前后对比:

// 不使用mapState时:
computed: {
    count () {
      return this.$store.state.count
    }
  }
// 使用mapState时:
computed: mapState({
       count: state => state.count,
})


如果在大批量的类似这种的计算属性的话,使用 mapState 会更加便捷。
(3)具体使用
store.js中:

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0,
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    reduction(state) {
      state.count--;
    }
  }
});
export default store;


组件中使用:

<template>
  <div id="salary-list-second">
    <button @click="incrementFun">+</button>
    <button @click="reductionFun">-</button>
    <p>{{currentCount}}</p>
  </div>
</template>
<script>
import { mapState } from "vuex";
export default {
  name: "salary-list-second",
  computed: mapState({
    currentCount: state => state.count
  }),
  methods: {
    incrementFun() {
      this.$store.commit("increment");
    },
    reductionFun() {
      this.$store.commit("reduction");
    }
  }
};
</script>
<style>
button {
  padding: 0.2rem;
}
p {
  line-height: 0.5rem;
}
</style>

4)mapState和计算属性前后写法的对比举例

// states 为对象时候,mapState转换前
computed: mapState({
    count: state => state.count,
    // 传字符串参数 'count' 等同于 `state => state.count`
    countAlias: 'count',
    // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    countPlusLocalState (state) {
        return state.count + this.localCount
    }
})

// states 为对象时候,mapState转换后
computed: {
    count() {
        return this.$store.state.count
    },
    countAlias() {
        return this.$store.state['count']
    },
    countPlusLocalState() {
        return this.$store.state.count + this.localCount
    }
}


使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。

2、getter
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性),就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
store.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    storeSalaryList: [
      {
        name: "马云",
        salaryAmount: 1000
      },
      {
        name: "马化腾",
        salaryAmount: 900
      },
      {
        name: "李彦宏",
        salaryAmount: 800
      }
    ]
  },
  getters: {
    doubleSalaryList(state) {
      let newArr = state.storeSalaryList.map(item => {
        return {
          name: item.name,
          salaryAmount: item.salaryAmount * 2 + " " + "$"
        };
      });
      return newArr;
    }
});
export default store;


组件中代码:

<template>
  <div id="salary-list-fisrt">
    <h2>财富榜</h2>
    <ol>
      <li v-for="(salary, index) in getterSalaryList"
          :key="index">
        {{salary.name}}的工资是:{{salary.salaryAmount}}
      </li>
    </ol>
  </div>
</template>
<script>
export default {
  name: "salary-list-first",
  computed: {
    getterSalaryList() {
      return this.$store.getters.doubleSalaryList;
    }
  }
};
</script>


3、mapGetters辅助函数
store.js中的代码:

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    storeSalaryList: [
      {
        name: "马云",
        salaryAmount: 1000
      },
      {
        name: "马化腾",
        salaryAmount: 900
      },
      {
        name: "李彦宏",
        salaryAmount: 800
      }
    ]
  },
  getters: {
    doubleSalaryList(state) {
      let newArr = state.storeSalaryList.map(item => {
        return {
          name: item.name,
          salaryAmount: item.salaryAmount * 2 + " " + "$"
        };
      });
      return newArr;
    },
    totalSalary(state) {
      let sum = 0;
      state.storeSalaryList.map(item => {
        sum += item.salaryAmount;
      });
      return sum * 2;
    }
  }
});
export default store;


组件中的应用:

<template>
  <div id="salary-list-fisrt">
    <h2>财富榜</h2>
    <ol>
      <li v-for="(salary, index) in myDoubleSalaryGetter"
          :key="index">
        {{salary.name}}的工资是:{{salary.salaryAmount}}
      </li>
    </ol>
    <span>工资总额是:{{myTotalSalary}} $</span>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
  name: "salary-list-first",
  computed: {
    ...mapGetters({
      myDoubleSalaryGetter: "doubleSalaryList",
      myTotalSalary: "totalSalary"
    })
  }
};
</script>

 

posted @ 2019-04-16 17:21  brave-sailor  阅读(1096)  评论(0编辑  收藏  举报