mapGetters辅助函数 #
简介 #
mapGetters 辅助函数将 store 中的 getter 映射到局部计算属性,简化组件中 Getter 的使用。
基本用法 #
数组语法 #
当映射的计算属性名称与 getter 名称相同时:
javascript
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters([
'doneTodos',
'doneTodosCount',
'isLoggedIn'
])
}
}
// 等价于
export default {
computed: {
doneTodos() {
return this.$store.getters.doneTodos
},
doneTodosCount() {
return this.$store.getters.doneTodosCount
},
isLoggedIn() {
return this.$store.getters.isLoggedIn
}
}
}
对象语法 #
当需要重命名时:
javascript
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters({
// 重命名
completedTodos: 'doneTodos',
completedCount: 'doneTodosCount',
// 保持原名
isLoggedIn: 'isLoggedIn'
})
}
}
使用场景 #
场景一:简单映射 #
vue
<template>
<div>
<p>Completed: {{ doneTodosCount }}</p>
<p v-if="isLoggedIn">Welcome back!</p>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters([
'doneTodosCount',
'isLoggedIn'
])
}
}
</script>
场景二:重命名避免冲突 #
vue
<template>
<div>
<p>Store Count: {{ storeCount }}</p>
<p>Local Count: {{ localCount }}</p>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {
localCount: 5
}
},
computed: {
...mapGetters({
storeCount: 'count' // 重命名避免与 localCount 冲突
})
}
}
</script>
场景三:混合使用 #
vue
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double: {{ doubleCount }}</p>
<p>Total: {{ total }}</p>
</div>
</template>
<script>
import { mapState, mapGetters } from 'vuex'
export default {
data() {
return {
bonus: 10
}
},
computed: {
// 映射 state
...mapState(['count']),
// 映射 getters
...mapGetters(['doubleCount']),
// 自定义计算属性
total() {
return this.count + this.bonus
}
}
}
</script>
模块中的使用 #
命名空间模块 #
javascript
// 使用命名空间前缀
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters('user', [
'isLoggedIn',
'userName'
]),
...mapGetters('cart', [
'cartTotal',
'cartItemCount'
])
}
}
使用 createNamespacedHelpers #
javascript
import { createNamespacedHelpers } from 'vuex'
const { mapGetters } = createNamespacedHelpers('user')
export default {
computed: {
// 直接映射,无需指定模块名
...mapGetters([
'isLoggedIn',
'userName'
])
}
}
重命名模块 Getter #
javascript
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters('user', {
userLoggedIn: 'isLoggedIn',
currentUserName: 'userName'
})
}
}
组合式 API 中使用 #
封装 mapGetters #
javascript
// composables/useMapGetters.js
import { computed } from 'vue'
import { useStore } from 'vuex'
export function useMapGetters(mapper) {
const store = useStore()
const result = {}
if (Array.isArray(mapper)) {
mapper.forEach(name => {
result[name] = computed(() => store.getters[name])
})
} else {
Object.keys(mapper).forEach(key => {
result[key] = computed(() => store.getters[mapper[key]])
})
}
return result
}
使用封装 #
vue
<script>
import { useMapGetters } from '@/composables/useMapGetters'
export default {
setup() {
const { doneTodos, doneTodosCount } = useMapGetters([
'doneTodos',
'doneTodosCount'
])
const { userLoggedIn, currentUserName } = useMapGetters({
userLoggedIn: 'user/isLoggedIn',
currentUserName: 'user/userName'
})
return {
doneTodos,
doneTodosCount,
userLoggedIn,
currentUserName
}
}
}
</script>
与其他辅助函数配合 #
完整示例 #
vue
<template>
<div>
<h2>User: {{ userName }}</h2>
<p>Cart: {{ cartItemCount }} items</p>
<p>Total: ${{ cartTotal }}</p>
<button @click="addToCart(product)">Add to Cart</button>
<button @click="logout">Logout</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
computed: {
// State
...mapState('user', ['profile']),
...mapState('products', ['currentProduct']),
// Getters
...mapGetters('user', ['userName', 'isLoggedIn']),
...mapGetters('cart', ['cartItemCount', 'cartTotal'])
},
methods: {
// Actions
...mapActions('cart', ['addToCart']),
...mapActions('user', ['logout'])
}
}
</script>
最佳实践 #
1. 合理命名 #
javascript
// 推荐:语义化命名
computed: {
...mapGetters({
currentUser: 'user/currentUser',
cartTotal: 'cart/total',
productCount: 'products/count'
})
}
// 不推荐:模糊命名
computed: {
...mapGetters({
data: 'user/currentUser', // 不清楚是什么
value: 'cart/total'
})
}
2. 按模块组织 #
javascript
// 推荐:按模块分组
computed: {
// User module
...mapGetters('user', ['isLoggedIn', 'userName']),
// Cart module
...mapGetters('cart', ['items', 'total']),
// Products module
...mapGetters('products', ['featuredProducts'])
}
3. 避免过度映射 #
javascript
// 如果只需要一个 getter,直接使用计算属性更清晰
computed: {
isLoggedIn() {
return this.$store.getters['user/isLoggedIn']
}
}
// 多个 getter 时使用 mapGetters
computed: {
...mapGetters('user', [
'isLoggedIn',
'userName',
'userEmail',
'userAvatar'
])
}
常见问题 #
1. Getter 不存在 #
javascript
// 问题:映射不存在的 getter
...mapGetters(['nonExistentGetter']) // undefined
// 解决:确保 getter 已定义
getters: {
nonExistentGetter: state => state.value
}
2. 命名冲突 #
javascript
// 问题:与组件方法或 data 冲突
export default {
data() {
return {
count: 0
}
},
computed: {
...mapGetters(['count']) // 冲突
}
}
// 解决:重命名
computed: {
...mapGetters({
storeCount: 'count'
})
}
3. 模块命名空间问题 #
javascript
// 问题:忘记命名空间
...mapGetters(['isLoggedIn']) // 找不到
// 解决:添加命名空间
...mapGetters('user', ['isLoggedIn'])
总结 #
mapGetters 使用要点:
| 语法 | 使用场景 | 示例 |
|---|---|---|
| 数组语法 | 名称相同 | ...mapGetters(['count']) |
| 对象语法 | 重命名 | ...mapGetters({ num: 'count' }) |
| 命名空间 | 模块映射 | ...mapGetters('user', ['name']) |
继续学习 Getter进阶,了解 Getter 的高级用法。
最后更新:2026-03-28