getters

通过前面章节的学习,我们知道在 Vue 组件中,可以利用计算属性来获取 state 中定义的状态,但是如果需要对这些状态数据进行二次加工或者添加一些业务逻辑,那么这些业务逻辑就只能写在各自组件的 computed 方法中,如果各组件都需要这类逻辑,那么就需要重复多次,getters 就可以用于解决这个问题(减少重复性),如示例代码 6-4-1 所示。

示例代码 6-4-1 getters 的使用
const store = new Vuex.Store({
    state: {
        count: 3,
    },
    getters: {
        getFormatCount(state) {
            // 对数据进行二次加工
            let str = '物料总价:' + (state.count * 10) + '元'
            return str;
        }
    }
})

const counter = {
    template: '<div>{{total}}</div>',
    computed: {
        total () {
            // this.$store.getters获取
            return this.$store.getters.getFormatCount
        }
    }
}

参考上面的代码,我们可以把 getters 理解成 store 的 “计算属性”,在 store 中添加 getters 设置,然后编写 getFormatCount 方法,接收一个 state 参数,就可以得到 state 的值,在该方法中对数据进行处理,最后把处理结果通过 return 返回。注意,在定义 getters 时是作为一个方法定义的,我们需要的是它的返回值,所以在使用 getters 时,要把它当作一个属性调用。在 counter 组件中,通过 this.$store.getters.getFormatCount 就可以获取处理之后的值。注意,这里的 getters 在通过属性 getFormatCount 访问时,如果 state 没有改变,那么每次调用都会从缓存中获取,这和组件的计算属性类似。

getFormatCount 方法除了有 state 参数之外,也可以接收另一个参数 getters,这样就可以调用其他 getters 的方法,达到复用的效果,代码如下:

getters: {
    otherCount(){ return '' },
    getFormatCount(state, getters) {
        return state.count + getters.otherCount
    }
}

使用 mapGetters 可以直接将 store 中的 getters 映射到局部的计算属性中,这样就可以直接在计算属性中使用 getter,而无须定义一个 computed 的属性值,然后在属性值中调用 getter 了,如示例代码 6-4-2 所示。

示例代码 6-4-2 getters 传参1
const store = Vuex.createStore({
    state: {
        count: 3,
    },
    getters: {
        getFormatCount(state) {
            let str = '物料总价:' + (state.count * 10) + '元'
            return str;
        }
    }
})

const counter = {
    template: '<div>{{total}}</div>',
    computed: {
        ...Vuex.mapGetters({
            "total":"getFormatCount"
        })
    }
}

Vue 组件中使用 getters 时,也支持传参,需要在 store 中定义 getters 时,通过 return 返回一个函数 function,如示例代码 6-4-3 所示。

示例代码 6-4-3 getters 传参2
const store = Vuex.createStore({
    state: {
        count: 3,
    },
    getters: {
        getFormatCount(state){
            // 返回一个function
            return(unit)=>{
                const str = '物料总价:' + (state.count * unit) + '元'
                return str;
            }
        }
    }
})
const counter = {
    template: '<div>{{total}}</div>',
    computed: {
        total () {
            // this.$store.getters调用getFormatCount(20)传参
            return this.$store.getters.getFormatCount(20)
        }
    }
}

注意,getters 在通过方法访问时,每次都会调用方法,而不是读取缓存的结果。

Vuex 中,mapGetters 是一个帮助函数,用于将 Vuex store 中的 getter 映射到组件的计算属性中。这简化了在组件中访问和使用 storegetter 的过程,使代码更清晰、更简洁。

为什么使用 mapGetters

GettersVuex 中类似于计算属性,通常用于对 store 中的状态进行计算或过滤。在组件中使用 mapGetters 可以轻松地将这些 getters 映射为计算属性,方便访问。

基本用法

mapGetters 有两种主要用法:

  1. 使用字符串数组:直接映射 store 中的 getter

  2. 使用对象:重命名计算属性或使用计算属性函数。

使用字符串数组

假设你的 Vuex store 中有如下 getters

const store = new Vuex.Store({
  state: {
    count: 0
  },
  getters: {
    doubleCount: state => state.count * 2,
    tripleCount: state => state.count * 3
  }
});

在组件中,你可以使用 mapGetters 将这些 getters 映射为计算属性:

<template>
  <div>
    <p>Double Count: {{ doubleCount }}</p>
    <p>Triple Count: {{ tripleCount }}</p>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters(['doubleCount', 'tripleCount'])
  }
};
</script>

在这个示例中,doubleCounttripleCount 被映射为组件的计算属性,直接引用 store 中的 getter

使用对象

当你需要重命名计算属性时,可以使用对象形式:

<template>
  <div>
    <p>Double: {{ double }}</p>
    <p>Triple: {{ triple }}</p>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters({
      double: 'doubleCount', // 将 `doubleCount` getter 映射为 `double`
      triple: 'tripleCount'  // 将 `tripleCount` getter 映射为 `triple`
    })
  }
};
</script>

在这个示例中:

  • double 映射了 store 中的 doubleCount getter

  • triple 映射了 store 中的 tripleCount getter

结合局部状态

如果组件中既需要使用 Vuex storegetter,又需要使用组件的局部状态,可以将它们结合起来:

<template>
  <div>
    <p>Double Count: {{ doubleCount }}</p>
    <p>Local Message: {{ localMessage }}</p>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  data() {
    return {
      localMessage: 'This is local'
    };
  },
  computed: {
    ...mapGetters(['doubleCount'])
  }
};
</script>

在这个示例中,组件既有来自 Vuex storedoubleCount getter,也有组件自己的 localMessage 数据。

模块化 Vuex

在使用 Vuex 模块化时,可以指定模块名称来访问嵌套的 getters

const store = new Vuex.Store({
  modules: {
    myModule: {
      state: () => ({
        count: 0
      }),
      getters: {
        doubleCount: state => state.count * 2,
        tripleCount: state => state.count * 3
      }
    }
  }
});

在组件中:

<template>
  <div>
    <p>Module Double Count: {{ doubleCount }}</p>
    <p>Module Triple Count: {{ tripleCount }}</p>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters('myModule', ['doubleCount', 'tripleCount'])
  }
};
</script>

在这个示例中,myModule 模块中的 doubleCounttripleCount getters 被映射为组件的计算属性。

mapGettersVuex 提供的一个非常方便的工具,可以简化在组件中访问 store getters 的过程。通过字符串数组和对象的两种形式,你可以灵活地映射 storegetters 到组件的计算属性中,并在需要时结合局部状态和模块化的 store 使用。这样,你的代码将更加清晰、简洁,并且易于维护。