Getter 类似于计算属性,用于从 store 的 state 中派生出新的状态。当多个组件需要对相同状态进行相同处理时,Getter 特别有用。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '学习 Vue', done: true },
{ id: 2, text: '学习 Vuex', done: false },
{ id: 3, text: '学习 Router', done: true }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
this.$store.getters.doneTodos
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
Getter 可以访问其他 getter:
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
Getter 可以返回一个函数,实现参数化查询:
getters: {
getTodoById: state => id => {
return state.todos.find(todo => todo.id === id)
}
}
this.$store.getters.getTodoById(1)
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['doneTodos', 'doneTodosCount'])
}
}
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters({
completedTodos: 'doneTodos',
completedCount: 'doneTodosCount'
})
}
}
getters: {
isLoggedIn: state => !!state.token,
userName: state => state.user?.name || '游客',
isAdmin: state => state.user?.role === 'admin',
userDisplayName: state => {
if (!state.user) return '游客'
return state.user.nickname || state.user.name || '未设置昵称'
}
}
getters: {
cartItems: state => state.cart.items,
cartTotal: state => {
return state.cart.items.reduce((total, item) => {
return total + item.price * item.quantity
}, 0)
},
cartCount: state => {
return state.cart.items.reduce((count, item) => {
return count + item.quantity
}, 0)
},
hasItems: state => state.cart.items.length > 0,
getItemById: state => id => {
return state.cart.items.find(item => item.id === id)
}
}
getters: {
filteredProducts: state => {
let products = state.products
if (state.filters.category) {
products = products.filter(p => p.category === state.filters.category)
}
if (state.filters.priceRange) {
const [min, max] = state.filters.priceRange
products = products.filter(p => p.price >= min && p.price <= max)
}
if (state.searchQuery) {
const query = state.searchQuery.toLowerCase()
products = products.filter(p =>
p.name.toLowerCase().includes(query) ||
p.description.toLowerCase().includes(query)
)
}
return products
},
productCount: (state, getters) => getters.filteredProducts.length
}
getters: {
paginatedList: state => {
const { page, pageSize } = state.pagination
const start = (page - 1) * pageSize
const end = start + pageSize
return state.items.slice(start, end)
},
totalPages: state => {
return Math.ceil(state.pagination.total / state.pagination.pageSize)
},
hasNextPage: (state, getters) => {
return state.pagination.page < getters.totalPages
},
hasPrevPage: state => {
return state.pagination.page > 1
}
}
getters: {
totalRevenue: state => {
return state.orders.reduce((sum, order) => sum + order.total, 0)
},
averageOrderValue: (state, getters) => {
if (state.orders.length === 0) return 0
return getters.totalRevenue / state.orders.length
},
ordersByStatus: state => {
return state.orders.reduce((acc, order) => {
const status = order.status
acc[status] = (acc[status] || 0) + 1
return acc
}, {})
}
}
getters: {
permissions: state => state.user?.permissions || [],
hasPermission: (state, getters) => permission => {
return getters.permissions.includes(permission)
},
hasAnyPermission: (state, getters) => permissions => {
return permissions.some(p => getters.permissions.includes(p))
},
hasAllPermissions: (state, getters) => permissions => {
return permissions.every(p => getters.permissions.includes(p))
}
}
Getter 会缓存结果,只有依赖的 state 变化时才重新计算:
getters: {
expensiveGetter: state => {
console.log('计算中...')
return state.items.map(item => {
// 复杂计算
return processedItem
})
}
}
多次访问只计算一次:
console.log(this.$store.getters.expensiveGetter)
console.log(this.$store.getters.expensiveGetter)
| 特性 | Getter | 计算属性 |
|---|---|---|
| 定义位置 | store | 组件 |
| 访问范围 | 全局 | 组件内 |
| 缓存 | 有 | 有 |
| 参数支持 | 返回函数 | 不支持 |
| 适用场景 | 跨组件复用 | 组件私有 |
getters: {
activeUsers: state => state.users.filter(u => u.active),
adminUsers: state => state.users.filter(u => u.role === 'admin'),
activeAdmins: (state, getters) => {
return getters.activeUsers.filter(u => u.role === 'admin')
}
}
Getter 要点: