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>